the startup terminal can take a sec to come up if your shell is slow.
when it's ready it grabs focus, and if you've opened the command palette
by then, that blurs the palette input and closes it. so it just
vanishes.
`add_center_terminal` focused the new terminal unconditionally. now it
skips the focus if a modal is open (`!has_active_modal`). one line at
the definition, covers all the call sites.
kept it terminal-specific like dinocosta framed it. could do a broader
workspace-level "don't steal from a modal" instead if you'd prefer.
two tests: modal stays focused after a background terminal spawns (fails
without the fix), and no-modal still focuses the terminal like before.
Fixes#60762.
Release Notes:
- Fixed a background terminal finishing startup closing the command
palette or an open picker
Found this while looking into a markdown preview issue. Clicking a
`path:row:column` target in the terminal treated the column as a byte
offset, so on lines with non-ASCII characters the cursor landed at mid
codepoint.
The real fix is just 3 lines and the rest is a refactor that extracts
the open and navigate logic so it can be reused later for cases like
markdown preview.
Release Notes:
- Fixed the cursor landing at the wrong column when clicking a
`path:row:column` link in the terminal for lines containing non-ASCII
characters.
VS Code has a command called "Toggle Maximize Editor Group" (`Cmd+K
Cmd+M`) that expands the active editor pane to fill the entire center
area, hiding editor split panes, but leaving docks and panels visible.
Zed's existing `ToggleZoom` hides all panels and is closer to VS Code's
Zen Mode. VS Code has both — it would be useful for Zed to as well.
This is particularly useful for people working on laptops, and has been
raised before (#32715, #4897, #32860), but the addition of the project
panel alongside the agent panel has made it more relevant. I work with
the editor split vertically, but with the project and agent panels both
visible, on a laptop screen there's really only room for a single editor
pane. This command makes it easy to switch to and from that mode.
**Behavior:**
- New action: `workspace::ToggleEditorZoom`
- When activated, the active editor pane expands to fill 100% of the
center/editor area, hiding sibling split panes
- Docks and panels remain visible and unaffected
- Toggling again restores the previous split layout
- If `ToggleZoom` is active, it unzooms first, then maximizes
Here's a demo:
https://github.com/user-attachments/assets/fcf6748e-6c45-4c4a-8d9f-f106c6cd58ea
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#32715
Release Notes:
- Added `workspace::ToggleEditorZoom` action to maximize the active
editor pane within the center area while keeping panels visible.
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#55934
Release Notes:
- Fixed terminal jitter when resizing vertically with content that
doesn't fill the available height.
---------
Co-authored-by: Nathan Sobo <nathan@zed.dev>
## Context
On Linux, `ctrl-q` is globally bound to `zed::Quit`. When a
`TerminalView` is focused, pressing `ctrl-q` quit the application
instead of forwarding the keycode to the shell, breaking programs like
`ftp`, `tig`, and any app that uses XON/XOFF flow control.
Windows already had the fix: its `Terminal` keymap context overrides
`ctrl-q` with `["terminal::SendKeystroke", "ctrl-q"]`. The Linux keymap
was simply missing that override.
Closes#58809
Manual test after fix below :
[Screencast from 2026-06-09
00-46-37.webm](https://github.com/user-attachments/assets/3d103b2a-bff1-4559-af1d-2a52d57a6b18)
## How to Review
- **`assets/keymaps/default-linux.json`** : One-line addition in the
`Terminal` context under the "Overrides for conflicting keybindings"
comment, mirroring the existing Windows entry.
- **`crates/terminal_view/src/terminal_view.rs`** : Regression test
`ctrl_q_is_forwarded_to_terminal_not_quit` (Linux-only, `#[cfg(target_os
= "linux")]`): loads the default keymap, focuses a display-only
terminal, simulates `ctrl-q`, and asserts the PTY receives byte `0x11`
instead of the quit action firing.
## 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 `ctrl-q` quitting Zed instead of being forwarded to the shell
when a terminal is focused on Linux
# Objective
Fix IME candidate window not following cursor position in the integrated
terminal when running fullscreen TUI applications like opencode.
When using IME (Input Method Editor) in Zed's terminal with fullscreen
TUI applications (e.g., opencode), the candidate window does not follow
the cursor position. This issue does not occur in normal terminal usage
(e.g., bash shell).
# Solution
The root cause was three-layer blocking preventing IME position updates
in ALT_SCREEN mode:
1. **ALT_SCREEN blocking**: `selected_text_range()` returned `None` in
ALT_SCREEN mode, causing `selected_bounds()` to return `None`
2. **Missing trigger**: `Event::Wakeup` did not call
`invalidate_character_coordinates()`, so cursor movement did not trigger
IME position updates
3. **Composition blocking**: `update_ime_position()` skipped updates
when `state.composing` was true
Fixes:
- Remove ALT_SCREEN check in `selected_text_range()` so IME position
updates work in fullscreen TUI apps
- Add `window.invalidate_character_coordinates()` in `Event::Wakeup` to
trigger IME position updates when terminal cursor moves
- Remove `state.composing` check in `update_ime_position()` to allow IME
position updates during text-input-v3 composition
- Remove unused `terminal` field from `TerminalInputHandler` struct
# Testing
**Did you test these changes? If so, how?**
- Yes, tested on Linux GNOME Wayland with iBus input method
- Verified IME candidate window correctly follows cursor in opencode
- Verified normal terminal usage with IME still works correctly
**Are there any parts that need more testing?**
- Other IMEs (fcitx, etc.) may need testing
**How can other people (reviewers) test your changes?**
1. Open Zed's integrated terminal
2. Run a fullscreen TUI application like `opencode`
3. Activate IME (e.g., iBus with Chinese input)
4. Type text and observe the IME candidate window follows the cursor
**What platforms did you test these changes on?**
- Linux (GNOME Wayland) - tested
- macOS - not tested (may have different IME behavior)
- Windows - not tested (different code path)
# 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 and icon
guidelines)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
# Showcase
<details>
<summary>Before</summary>
<video
src="https://github.com/user-attachments/assets/ee2fac4e-801b-49af-a57e-32ce25e01db5"
width="320" height="180" />
</details>
<details>
<summary>After</summary>
<video
src="https://github.com/user-attachments/assets/c669ea99-2ffc-4179-b587-a47873e33e70"
width="320" height="180" />
</details>
---
Release Notes:
- Fixed IME candidate window not following cursor in terminal TUI apps
## Summary
- Fixed the terminal inline assist tab bar tooltip so it resolves the
keybinding from the active terminal view.
- The bug happened when the initial terminal was closed and a new
terminal was opened: the tab bar button kept a cached focus handle for
the old terminal, so tooltip keybinding lookup could no longer find the
terminal key context.
- The button is now created while rendering the tab bar with the current
terminal view's focus handle, avoiding stale focus handles as terminals
are closed and recreated.
## Validation
- `cargo fmt --package terminal_view --check`
- `cargo check -p terminal_view --message-format short`
Release Notes:
- Fixed the terminal inline assist toolbar tooltip not showing its
keybinding after reopening terminals.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@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)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable
When files are dragged into the terminal, paths were formatted using
Rust's Debug format (`{path:?}`), which wraps them in double quotes.
This caused issues with programs like Claude Code that parse bare paths
from terminal input — quoted paths were treated as plain text instead of
file references.
This change replaces double-quote wrapping with backslash escaping for
special shell characters on Unix, which is both valid shell syntax and
compatible with path-parsing tools running in the terminal. On non-Unix
platforms the previous behavior is preserved.
Tested on macOS only. Unable to verify Windows behavior.
Fixes#57471
Release Notes:
- Fixed/ file drag-and-drop into terminal inserting double-quoted paths,
which prevented tools like Claude Code from recognizing them as file
references.
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
Closes#39159
## Summary
• resolve remote terminal path candidates outside known worktrees
through `Project::resolve_abs_path`
• keep the local filesystem backed resolution path unchanged
• preserve the existing preference for direct in-worktree matches when
the terminal cwd is already inside a worktree
• add regression coverage for both absolute and cwd-relative remote
external paths
### Why
The hyperlink parser wasn't the bug. `terminal_path_like_target` already
knew how to parse these paths. The actual problem was that remote
projects had no equivalent of the local background existence check.
After worktree lookup failed, remote projects only fell back to worktree
traversal, so cmd-click on `/tmp/a.txt` in an SSH remote terminal
no-op'd.
The project layer already has remote absolute-path resolution via
`Project::resolve_abs_path`, so the right fix is to use that existing
path for remote candidates instead of pretending remote projects cannot
resolve paths outside their worktrees.
## Verification
• `cargo test -p terminal_view terminal_path_like_target --quiet`
• `cargo test -p terminal_view --quiet`
## Manual
• Verified locally on my MBP w/ a stateless Zed build using SSH to self
(`localhost`)
• Opened `/tmp/zed-39159-project` as a remote project
• Confirmed cmd-click opens `/tmp/zed-39159-external/a.txt`
• Confirmed cmd-click opens `zed-39159-external/b.txt` from `cwd=/tmp`
• Confirmed in-worktree paths still open correctly
• Confirmed nonexistent external paths do not open bogus targets
Release Notes:
- Fixed remote terminal path opening so cmd-click can open files outside
the project worktree.
Both cloning and dropping of these has quite a bit of overhead (despite
them being snapshots), so avoid where possible, especially in display
map syncing
Release Notes:
- N/A or Added/Fixed/Improved ...
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
Refactor to isolate alacritty types into the terminal crate and offers
comparable apis where needed for similar functionality. However, these
are Zed-owned types instead of the dependency leaking across multiple
crates, making alacritty an implementation detail of the terminal crate.
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
Resolves https://github.com/zed-industries/zed/issues/57999
This diff fixes the macOS Edit menu showing Copy and Paste as disabled
when a terminal is focused. Terminal shortcuts already worked because
keybindings dispatch `terminal::Copy` and `terminal::Paste`, but the app
menu validates `editor::Copy` and `editor::Paste`, which the terminal
view did not expose.
With this change, the terminal view handles the editor Copy and Paste
actions by delegating to the existing terminal copy and paste paths.
This keeps keyboard behavior unchanged while allowing menu validation
and menu dispatch to work correctly for focused terminals.
Release Notes:
- Fixed `Copy` and `Paste` being disabled in the macOS `Edit` menu when
a terminal is focused.
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
I ran into this while using lazygit: the Shift navigation keys were
being captured by Zed to scroll the terminal buffer instead of being
passed through to the program.
Capturing them makes sense in the normal terminal case, where the user
wants to scroll and Shift has no other meaning. But in alternate-screen
TUIs like lazygit, less, or neovim, terminal scrollback isn't relevant,
so we can forward these keys to the program while it's open.
Release Notes:
- Fixed Shift+Up, Shift+Down, Shift+Home, and Shift+End in terminal TUIs
like lazygit, less, and neovim.
---------
Co-authored-by: John Tur <john-tur@outlook.com>
When the agent mentions a file path inside `backticks` (e.g. ``
`src/main.rs` `` or `` `src/main.rs:42` ``), the rendered code span now
becomes a clickable link in the agent panel. Clicking opens the
referenced file in the workspace, jumping to the right line and column
when present.
## How it works
- **Shared path resolution.** Extracted `OpenTarget` and the
workspace/worktree resolution logic out of
`terminal_view::terminal_path_like_target` into a new
`workspace::path_link` module so both the terminal and the agent panel
can use the same code. Includes a `sanitize_path_text` helper ported
from the terminal's URL/punctuation handling. Pure refactor — terminal
behavior is unchanged.
- **`markdown` crate hook.** Added
`MarkdownElement::on_code_span_link(callback)`. When the callback
returns `Some(url)` for a given code span's contents, the existing
`push_link` machinery wires up cmd-hover, hit testing, and the existing
`on_url_click` callback. When it returns `None`, the code span renders
as before. The hook is opt-in, so `markdown` stays workspace-agnostic.
- **Agent panel wiring.** `render_agent_markdown` constructs an
`AgentCodeSpanResolver` that snapshots the project's visible worktree
entries plus their file extensions. `try_resolve` does a cheap
synchronous heuristic check (path must contain `/`/`\` or end in an
extension present in the workspace, can't be a URL, can't be all digits,
etc.) and then looks the candidate up in the per-worktree
`HashSet<Arc<RelPath>>`. On a hit it returns a `MentionUri::File` or
`MentionUri::Selection` URI, which the existing `thread_view::open_link`
already knows how to open at the right line.
## Edge cases handled
- Code spans inside fenced code blocks stay plain (gated on
`builder.code_block_stack.is_empty()`, matching how regular markdown
links behave).
- Trailing prose punctuation (`` `src/main.rs.` ``) is stripped before
lookup.
- Identifiers like `` `String` ``, `` `await` ``, `` `npm run dev` ``
stay plain — they don't pass the path-like heuristic.
- Cross-platform path separators handled via the per-worktree
`PathStyle`.
## Tests
- `crates/markdown` — unit test asserting code spans become links when
the callback returns `Some`, and stay plain when it doesn't.
- `crates/agent_ui` — unit test for `AgentCodeSpanResolver::try_resolve`
covering hits with and without a `:line` suffix, misses, identifiers,
and trailing punctuation.
- Existing `terminal_view` tests cover the moved resolution code
(unchanged behavior).
## Notes
- There's currently a temporary `log::info!` in
`AgentCodeSpanResolver::try_resolve` that reports per-call worktree-walk
timing and a cumulative total. Kept in for now to verify the feature
isn't being called excessively during streaming renders. Can be removed
before merge.
- Resolution is sync-only against worktree entries; absolute paths
outside the workspace are not resolved (would require an async re-render
path).
Closes AI-277
Release Notes:
- Made file paths in `backticks` clickable in the agent panel; clicking
opens the referenced file at the given line when present.
Resolves https://github.com/zed-industries/zed/issues/56138
This diff hides terminal agent actions from context menus shown by
embedded terminal views, such as terminal tool output in agent threads.
Those surfaces render through `TerminalView`, but they are not normal
interactive terminal panes, and actions like Inline Assist and Add to
Agent Thread do not currently resolve the embedded terminal as their
target.
Previously, choosing Inline Assist from terminal tool output could
target the workspace’s active editor instead of the terminal output. The
context menu now limits these agent actions to non-embedded terminal
views, so regular terminal panes keep their existing behavior while
terminal tool output no longer offers actions that cannot resolve to it.
Add to Agent Thread _could_ make sense for embedded terminal selections
in the future, but it would need explicit target-resolution support for
focused embedded terminals. This change keeps that as separate follow-up
work instead of leaving a misleading menu item that does not reliably
act on the selected tool output.
Release Notes:
- Fixed embedded terminal context menus showing agent actions that could
target the wrong item.
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
Closes#55619
### Summary
- Route `buffer_search::UseSelectionForFind` through
`BufferSearchBar::deploy` instead of updating the query editor directly.
- Add an explicit seed-query override to `deploy`, so the Cmd-E action
can force `SeedQuerySetting::Always` while regular deploy callers
continue to pass `None` and respect the user’s
`seed_search_query_from_cursor` setting.
- By going through `deploy`, Cmd-E now also runs the search path that
keeps buffer-search navigation state in sync:
- shows/initializes the search bar for the active searchable item
- applies the seeded query via `search_suggested`
- calls `search`, which updates the query editor, search options, active
search query, search history, and macOS find pasteboard
- refreshes `searchable_items_with_matches` and `active_match_index`
- activates the current match after the search completes
- This ensures the subsequent Cmd-G action has the expected active
query, match list, search token, and active match index to select the
next result.
- Add a macOS-only end-to-end regression test using the default macOS
keymap with `simulate_keystrokes("cmd-e")` and
`simulate_keystrokes("cmd-g")`.
### Validation
- `cargo test -p search test_cmd_e_then_cmd_g_uses_selection_for_find`
- `cargo fmt --check --package search --package zed_actions`
- `./script/check-keymaps`
- `cargo check -p search`
- `cargo check -p workspace`
- `cargo check -p vim`
Release Notes:
- Fixed macOS Cmd-E/Cmd-G find behavior so Cmd-E seeds find from the
cursor or selection and Cmd-G advances through the newly seeded matches.
Experiment with allowing users to manage terminal sessions along with
threads in the sidebar.
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: Bennet Bo Fenner <bennetbo@gmx.de>
This adds the functionality to support pasting the file path of an item
when the copied item supports it. This mirrors the behavior of
`Terminal.app` on macOS.
This only implements the functionality on macOS but could be extended to
other platforms.
I find this convenient when I'm using Finder to navigate around the file
system and I want to copy a directory or file path and put it in the
terminal. You can copy the item from Finder and paste it into the
terminal and it will write out the full path of the item, making it easy
to change directories or provide path parameters to commands.
Release Notes:
- Added path pasting functionality in terminal
Right now the terminal rendering code applies a minimum contrast value
(which is good, and for accessibility) to colors that appear, there was
already an exemption from this for 24bit color specification, because
the application explicitly asked for that color, so it should be
rendered that color.
My change changes that exemption to also include ansi colors 16-255,
because these are also set explicitly, the normal, non-exempt case is
now the default ansi colors, 0-15, these are set by the theme and are
usually specified as just 'red' or 'green', hence the importance of the
min contrast.
Heres what the gradient ramp from the original issue looks like now:
<img width="944" height="1123" alt="Screenshot 2026-04-22 at 6 45 43 PM"
src="https://github.com/user-attachments/assets/918d62db-ed8e-475c-9ec1-c60187ad4b5e"
/>
This matches ghostty and VSCodium from the original issue.
test prevents regressions but idk, maybe not nessecary.
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#54396
Release Notes:
- terminal: Improved 256 color ansi rendering
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
This fixes an issue where due to the scrollbar appearing, the reported
content size would shift, causing issues in the process. We now actually
always reserve space for the scrollbar appropriately as described in
https://github.com/zed-industries/zed/pull/33636 initially.
Release Notes:
- Fixed an issue where the scrollbar could cause a layout shift in the
terminal.
---------
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Painting primitives at non-integer pixel coordinates produces blurry
output. Pixel snapping converts layout coordinates into integer
device-pixel coordinates so painted edges land exactly on physical pixel
boundaries.
Non-integer coordinates can arise for several reasons, including:
- flex distribution, percentages, centering, and text measurement can
produce fractional element sizes and positions;
- at fractional scale factors (for example 125% or 150%), integer
logical-pixel values can map to non-integer device-pixel values.
We pixel-snap by rounding in device-pixel space, after multiplying by
`scale_factor`, so that snapping targets physical pixels. Bounds are
divided by `scale_factor` before being returned to GPUI.
Midpoints are rounded toward zero. This is a stylistic choice: a
1-logical-pixel line at 150% scale should render as 1 dp rather than 2
dp.
Pixel snapping is done in two phases:
1. Pre-layout metric snapping. Before Taffy computes layout, all
authored absolute lengths are rounded in `to_taffy`. This includes
borders, padding, gaps, and explicit sizes. Custom-measured leaf nodes
have their measured sizes rounded up to integer device-pixel lengths.
2. Post-layout edge snapping. After Taffy resolves the tree, layout
relationships such as flex shares, grid tracks, percentages, and
centering can produce new fractional edge positions. Boxes now have
edges in absolute coordinates, and snapping must decide where those
edges land on the device-pixel grid.
Ideally, post-layout snapping would satisfy:
- Edge closure. Two raw layout edges at the same absolute position
should snap to the same pixel column.
- Translation stability. A component's internal geometry should not
change when it moves to a new absolute position.
These goals are in tension because rounding is not associative. The
simple local schemes make different tradeoffs:
- Absolute edge rounding gives each window coordinate one answer, so
coincident edges always close globally. But a span's snapped length is
`round(far) - round(near)`, which may change by 1 dp as its absolute
origin moves.
- Parent-relative edge rounding rounds each child inside its parent's
coordinate space. This guarantees translation stability, but a shared
edge reached through different parents can accumulate different
rounding, causing non-closure between cousins.
- Length rounding rounds each width, height, and thickness independently
and then places boxes from those rounded lengths. Sizes stay stable
under translation, but neighboring boxes derive their shared boundary
from different sources, so closure is not guaranteed.
We apply absolute edge rounding for each element's outer box in
post-layout rounding to preserve closure. Border and padding widths are
not touched by post-layout rounding; they keep their pre-layout rounded
value so that they remain stable under translation.
This gives both closure and translation stability in the case that all
local metrics are integer device-pixel lengths. Pre-layout rounding
covers that in most cases. The exception is metrics resolved by layout
relationships, such as percentages. Outer box edges will still close
globally, and painted border widths are still snapped independently, but
the raw content-box origin can carry a 1 dp residual into descendants.
---
Fixes https://github.com/zed-industries/zed/issues/46360
Fixes https://github.com/zed-industries/zed/issues/44528
Fixes https://github.com/zed-industries/zed/issues/40282
Fixes https://github.com/zed-industries/zed/issues/42257
---
Release Notes:
- Fixed potentially blurry appearance of UI elements when using
fractional display scaling.
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
Closes#50844
## Summary
- When right-clicking a word in the terminal with no prior selection,
`select_word_at_event_position` queues the selection as an
`InternalEvent` that only syncs to `last_content` on the next update
cycle.
- The context menu was reading `last_content.selection_text` before the
sync, so "Add to Agent Thread" was missing until the second right-click.
- Pass `has_selection` into `deploy_context_menu` from the call site,
where we already know whether a word was just selected.
## Test plan
- [x] Open a terminal in Zed
- [x] Run a command that produces output (e.g. `echo foo bar baz`)
- [x] Ensure there is no existing selection
- [x] Right-click on a word — "Add to Agent Thread" appears on the first
right-click
- [x] Right-click with an existing selection — "Add to Agent Thread"
still appears
- [x] Right-click with no text under cursor — context menu still works
correctly
## Videos:
### Before
[agent_test_before.webm](https://github.com/user-attachments/assets/d913a05b-6189-40a4-8eee-3660be8c3647)
### After
[agent_test_after.webm](https://github.com/user-attachments/assets/ceacc617-71b2-442f-a150-305867f9dd5f)
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
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- Fixed "Add to Agent Thread" missing from terminal context menu on
first right-click when no prior selection existed.
---------
Co-authored-by: Lukas Wirth <lukas@zed.dev>
When opening a terminal in a remote project, skip local-only path
operations (home dir fallback, shell expansion, is_dir checks) so the
remote shell opens in the remote user’s home directory by default.
Closes#49613.
Before you mark this PR as ready for review, make sure that you have:
- [ ] 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:
- Prevent local path resolution for remote terminals
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
Followup to #47531 to use the gpui feature in Zed. This just plumbs the
"system bell" feature into the terminal, behind a new setting (enabled
by default, like most other terminal applications).
Closes#5303
Relates to
https://github.com/zed-industries/zed/issues/40826#issuecomment-3684556858
Release Notes:
- Added audible BEL to Terminal; can be enabled by setting
`terminal.bell` to `"system"`.
---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Ben Kunkle <Ben.kunkle@gmail.com>
When opening a remote session, sometimes you get a message:
/bin/bash: line 1: cd: /Users/pep: No such file or directory
which suggests that that the local home dir (/Users/pep) is used for the
remote terminal session, where it should be something like /home/ubuntu.
Release Notes:
- Fixed remote terminals incorrectly trying to change to a local home
directory.
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
## What
When terminal cursor shape is set via escape sequences (e.g. `\e[6 q`
for bar, `\e[4 q` for underline), the cursor looks identical whether the
terminal is focused or unfocused. Block cursors already convert to a
hollow outline when unfocused, but bar and underline were missing this
treatment.
## How
Added unfocused guards for `Beam` and `Underline` in the cursor shape
match in `terminal_element.rs`, converting them to `Hollow` when the
terminal loses focus. This follows the same pattern already used for
`Block`.
## Why this approach
A hollow block outline is the clearest unfocused signal and stays
consistent with the existing Block behavior. Alternative approaches like
dimming opacity or drawing outlined versions of bar/underline were
considered, but a 2px-wide outlined bar would be nearly invisible at
normal font sizes.
## Demo:
Before:
https://github.com/user-attachments/assets/81d49899-0837-42fe-a68f-4eb745892af6
After:
https://github.com/user-attachments/assets/a4444e28-5835-4c9f-872f-e9ce8c4805a0Closes#52716
Release Notes:
- Fixed terminal bar and underline cursors set via escape sequences not
visually distinguishing between focused and unfocused states
## Context
Red and blue have inherently low perceptual luminance in APCA — pure
default Lc 45 threshold. This caused ensure_minimum_contrast to lighten
them, washing out the color to pink/lavender.
When an application explicitly specifies an RGB value via
ESC[38;2;R;G;Bm,
that color should be rendered as-is. Named and indexed colors continue
to be contrast-adjusted since they come from theme mappings
[zed-colors-before.webm](https://github.com/user-attachments/assets/1adb8c95-5dec-4744-b6f8-38f085602ef4)
[zed-colors-after.webm](https://github.com/user-attachments/assets/1968db26-9c02-48cf-9542-86a6c39899c0)
Closes: #50396
<!-- What does this PR do, and why? How is it expected to impact users?
Not just what changed, but what motivated it and why this approach.
Link to Linear issue (e.g., ENG-123) or GitHub issue (e.g., Closes#456)
if one exists — helps with traceability. -->
## Self-Review Checklist
<!-- Check before requesting review: -->
- [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 true-color render in terminal
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:
- Added "New Center Terminal" button to window context menu
"New Terminal" only opens a new terminal window in the dedicated
terminal view, while "New Center Terminal" opens a new terminal in the
currently active view.
"+"/"New..." context menu
<img width="487" height="318" alt="Screenshot_20260411_184840"
src="https://github.com/user-attachments/assets/7c1597cf-5638-4d76-a486-537033cb8da5"
/>
Right click context menu
<img width="422" height="386" alt="Screenshot_20260411_184904"
src="https://github.com/user-attachments/assets/4e557e21-8839-4226-b704-87e37fbd8f46"
/>
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#53056.
Release Notes:
- Fixed terminal tabs losing keyboard focus after switching tabs on Linux X11
Context
The markdown preview had no search functionality — pressing Ctrl+F did
nothing. This PR implements the SearchableItem trait for
MarkdownPreviewView, enabling in-pane text search with match
highlighting and navigation.
Changes span four crates:
- project: Added SearchQuery::search_str() — a synchronous method to
search plain &str text, since the existing search() only works on
BufferSnapshot.
- markdown: Added search highlight storage to the Markdown entity and
paint_search_highlights to MarkdownElement. Extracted the existing
selection painting into a reusable paint_highlight_range helper to avoid
duplicating quad-painting logic.
- markdown_preview: Implemented SearchableItem with full match
navigation, active match tracking, and proper SearchEvent emission
matching Editor behavior.
- Keymaps: Added buffer_search::Deploy bindings to the MarkdownPreview
context on all three platforms.
The PR hopefully Closes
https://github.com/zed-industries/zed/issues/27154
How to Review
1. crates/project/src/search.rs — search_str method at the end of impl
SearchQuery. Handles both Text (AhoCorasick) and Regex variants with
whole-word and multiline support.
2. crates/markdown/src/markdown.rs — Three areas:
- New fields and methods on Markdown struct (~line 264, 512-548)
- paint_highlight_range extraction and paint_search_highlights (~line
1059-1170)
- The single-line addition in Element::paint (~line 2003)
3. crates/markdown_preview/src/markdown_preview_view.rs — The main
change. Focus on:
- SearchEvent::MatchesInvalidated emission in schedule_markdown_update
(line 384)
- EventEmitter<SearchEvent> and as_searchable (lines 723, 748-754)
- The SearchableItem impl (lines 779-927), especially active_match_index
which computes position from old highlights to handle query changes
correctly
4. Keymap files — Two lines each for Linux/Windows, one for macOS.
Self-Review Checklist
- [ x ] I've reviewed my own diff for quality, security, and reliability
- [ x ] Unsafe blocks (if any) have justifying comments (no unsafe)
- [ x ] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
(should be 😄 )
- [ - ] Tests cover the new/changed behavior (not sure)
- [ - ] Performance impact has been considered and is acceptable (I'm
not sure about it and it would be nice to see experienced people to
test)
Release Notes:
- Added search support (Ctrl+F / Cmd+F) to the markdown preview
---------
Co-authored-by: Conrad Irwin <conrad.irwin@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
Release Notes:
- Removed legacy Text Threads feature to help streamline the new agentic
workflows in Zed. Thanks to all of you who were enthusiastic Text Thread
users over the years ❤️!
---------
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
- **Remove some of the settings types from ui**
- **drag settings-less ui across the line**
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
---------
Co-authored-by: Lukas Wirth <me@lukaswirth.dev>
This PR adds the ability to change both the terminal and agent panels
between fixed and flexible sizing using the status bar button right
click menu. The value persists in your settings, similar to the dock
position.
I've also slightly tweaked the styling of the "Dock Left" and "Dock
Right" items in the right-click menu, adding the current value as an
item with a check beside it, to make it clear that it's a selectable
option.
Release Notes:
- N/A
## Context
Fixes#52063
This change hides the cursor in embedded terminal mode when not focused.
Embedded mode is used for read-only terminal output (like the Agent
panel). Showing a cursor in a read-only context when unfocused is
confusing, so we suppress it.
<img width="549" height="496" alt="Screenshot 2026-03-25 at 12 03 15"
src="https://github.com/user-attachments/assets/20b29c28-85a7-4f5e-87ea-acf47d15d506"
/>
## How to Review
The change is in a single file:
`crates/terminal_view/src/terminal_view.rs:754-761`.
Focus on the `should_show_cursor()` method
Verify the logic correctly hides the cursor only when both conditions
are met (Embedded mode AND not focused).
## Self-Review Checklist
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments (N/A - no unsafe
code)
- [x] The content is consistent with the UI/UX checklist
- [x] Tests cover the new/changed behavior (behavior is minimal UI fix,
existing tests should cover)
- [x] Performance impact has been considered and is acceptable
(negligible)
Release Notes:
- Fixed cursor visibility issue in embedded terminal panels