Add support for scrolling the contents rendered aside an
`editor::code_context_menus::CodeContextMenu` by introducing the
`scroll_aside` method.
For now this method is only implemented for the
`CodeContextMenu::Completions` variant, which will scroll the aside
contents for an `editor::code_context_menus::CompletionsMenu` element,
as a `ScrollHandle` is added to the aside content that is rendered.
In order to be possible to trigger this via keybindings, a new editor
action is introduced, `ContextMenuScrollAside`, which accepts a number
of lines or pages to scroll the content by.
Lastly, the default keymaps for both MacOS and Linux, as well as for
Zed's vim mode, are updated to ensure that the following keybindings are
supported when a completion menu is open and the completion item's
documentation is rendered aside:
- `ctrl-e`
- `ctrl-y`
- `ctrl-d`
- `ctrl-u`
### Recording
https://github.com/user-attachments/assets/02043763-87ea-46f5-9768-00e907127b69
---
Closes#13194
Release Notes:
- Added support for scrolling the documentation panel shown alongside
the completion menu in the editor with `cltr-d`, `ctrl-u`, `ctrl-e` and
`ctrl-y`
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Co-authored-by: MrSubidubi <finn@zed.dev>
Closes#35787Closes#17890Closes#28789Closes#36495
How it works:
For highlights (and selections) within the visible rows of the editor,
we split them row by row. This is efficient since the number of visible
rows is constant. For each row, all highlights and selections, which may
overlap, are flattened using a line sweep. This produces non-overlapping
consecutive segments for each row, each with a blended background color.
Next, for each row, we split text runs into smaller runs to adjust its
color using APCA contrast. Since both text runs and segment are
non-overlapping and consecutive, we can use two-pointer on them to do
this.
For example, a text run for the variable red might be split into two
runs if a highlight partially covers it. As a result, one part may
appear as red, while the other appears as a lighter red, depending on
the background behind it.
Result:
<img width="1458" height="949" alt="image"
src="https://github.com/user-attachments/assets/4814c93d-12e7-4b4d-8542-d912acccfb8e"
/>
<img width="1459" height="952" alt="image"
src="https://github.com/user-attachments/assets/9e497b6c-3e66-43e8-8e5b-f634dd5ee8d3"
/>
<img width="1457" height="621" alt="image"
src="https://github.com/user-attachments/assets/8dfa6ce5-f46b-45b9-8008-66169d5aecd4"
/>
Release Notes:
- Improved text contrast when selected or highlighted in the editor.
This pull request refactors the `KeybindingKeystroke` struct and related
code to improve platform abstraction. The changes centralize
platform-specific logic within `KeybindingKeystroke` and update its
usage throughout the codebase, making the API more consistent and less
error-prone.
Release Notes:
- N/A
This PR adds the ability for a user to select one or more blocks of text
and wrap each selection in an HTML tag — which works by placing multiple
cursors inside the open and close tags so the appropriate element name
can be typed in to all places simultaneously.
This is similar to the emmet "Wrap with Abbreviation" functionality
discussed in #15588 but is a simpler version that does not rely on
Emmet's language server.
Here's a preview of the feature in action:
https://github.com/user-attachments/assets/1931e717-136c-4766-a585-e4ba939d9adf
Some notes and questions:
- The current implementation is a hardcoded with regards to supported
languages. I'd love some direction on how much of this information to
push into the relevant language structs.
- I can see this feature as something that languages added by an
extension would want to enable support for — is this something you'd
want?
- The syntax is hardcoded to support HTML/XML/JSX-like languages. I
don't suppose this is a problem but figured I'd point it out anyway.
- I called it "Wrap in tag" but open to whatever naming you feel is
appropriate.
- The implementation doesn't use `manipulate_lines` — I wasn't sure how
make use of that without extra overhead / bookkeeping — does this seem
fine?
- I could also investigate adding wrap in abbreviation support by
communicating with the Emmet language server but I think I'll need some
direction on how to handle Emmet's custom LSP message. I could do this
either in addition to or instead of this feature — though imo this
feature is a nice "shortcut" regardless.
Release Notes:
- Added a new "Wrap Selections in Tag" action that lets you wrap one or
more selections in tags based on language. Works in HTML, JSX, and
similar languages, and places cursors inside both opening and closing
tags so you can type the tag name once and apply it everywhere.
---------
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
This is a pure refactor that consolidates all SSH remoting logic such
that it should be straightforward to add another transport to the
remoting system.
Release Notes:
- N/A
---------
Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
Closes#36300
This PR follows Windows conventions by introducing
`KeybindingKeystroke`, so shortcuts now show up as `ctrl-shift-4`
instead of `ctrl-$`.
It also fixes issues with keyboard layouts: when `use_key_equivalents`
is set to true, keys are remapped based on their virtual key codes. For
example, `ctrl-\` on a standard English layout will be mapped to
`ctrl-ё` on a Russian layout.
Release Notes:
- N/A
---------
Co-authored-by: Kate <kate@zed.dev>
<img width="1988" height="1420" alt="multi-buffer-icons-git-diff"
src="https://github.com/user-attachments/assets/48f9722f-ca09-4aa7-ad7a-0b7e85f440d9"
/>
Unfortunately, `cargo format` decided to reformat everything. Probably,
because of hitting the right margin, no idea. The essence of this change
is the following:
```rust
.map(|path_header| {
let filename = filename
.map(SharedString::from)
.unwrap_or_else(|| "untitled".into());
let path = path::Path::new(filename.as_str());
let icon =
FileIcons::get_icon(path, cx).unwrap_or_default();
let icon = Icon::from_path(icon).color(Color::Muted);
let label = Label::new(filename).single_line().when_some(
file_status,
|el, status| {
el.color(if status.is_conflicted() {
Color::Conflict
} else if status.is_modified() {
Color::Modified
} else if status.is_deleted() {
Color::Disabled
} else {
Color::Created
})
.when(status.is_deleted(), |el| el.strikethrough())
},
);
path_header.child(icon).child(label)
})
```
Release Notes:
- Added file icons to multi buffer view
Flycheck commands are global and makes sense to fall back to looking up
project's rust-analyzer even if the commands are run on a non-rust
buffer. If multiple rust-analyzers are found in the project, avoid
ambiguous commands and bail (as before).
Closes #ISSUE
Release Notes:
- Made it possible to run rust-analyzer's flycheck actions from anywhere
in the project
This fixes a panic I randomly ran into whilst mistyping in the command
palette: I accidentally ran `pane: swap item right`in a state where no
items were opened in my active pane. We were checking for `index + 1 ==
self.items.len()` there when it really should be `>=`, as otherwise in
the case of no items this panics.
This PR fixes the bug, adds a test for both the panic as well as the
actions themselves (they were untested previously). Lastly (and mostly),
this also cleans up a bit around existing actions to update them with
how we generally handle actions now.
Release Notes:
- Fixed a panic that could occur with the `pane: swap item right`
action.
Users now accept ToS from Zed's website when they sign in to Zed the
first time. So it's no longer possible that a signed in account could
not have accepted the ToS.
Release Notes:
- N/A
---------
Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
Introduce `min_words_query_len` threshold for automatic word completion
display, and set it to 3 by default.
Re-enable word completions in Markdown and Plaintext.
Release Notes:
- Introduced `min_words_query_len` threshold for automatic word
completion display, and set it to 3 by default to make them less
intrusive
## Summary
Fixes cursor movement behavior in protected files (like Default
Settings) when pressing backspace or delete keys.
Previously, these keys would cause unwanted cursor movement instead of
being ignored as expected in read-only files.
## Changes
- Added read-only checks to `backspace()` and `delete()` methods in the
editor
- Consistent with existing pattern used by other editing methods
(`indent()`, `outdent()`, `undo()`, etc.)
## Test Plan
1. Open Default Settings in Zed
2. Place cursor at arbitrary position (not at start/end of file)
3. Press backspace - cursor should remain in place (no movement)
4. Press delete - cursor should remain in place (no movement)
Fixes#36302
Release Notes:
- Fixed backspace and delete keys moving caret in protected files
Co-authored-by: Claude <noreply@anthropic.com>
Closes#34445
Now we open a multi-buffer consisting of buffers that have updated,
renamed file imports.
Only local is handled, for now.
Release Notes:
- Fixed an issue where renaming a file would not update imports in
related files if they are not already open.
Instead of holding a connection for potentially long LSP queries (e.g.
rust-analyzer might take minutes to look up a definition), disconnect
right after sending the initial request and handle the follow-up
responses later.
As a bonus, this allows to cancel previously sent request on the local
Collab clients' side due to this, as instead of holding and serving the
old connection, local clients now can stop previous requests, if needed.
Current PR does not convert all LSP requests to the new paradigm, but
the problematic ones, deprecating `MultiLspQuery` and moving all its
requests to the new paradigm.
Release Notes:
- Improved resource usage when querying LSP over Collab
---------
Co-authored-by: David Kleingeld <git@davidsk.dev>
Co-authored-by: Mikayla Maki <mikayla@zed.dev>
Co-authored-by: David Kleingeld <davidsk@zed.dev>
This may be responsible for a panic that we've been seeing with
increased frequency in agent2 threads.
Release Notes:
- N/A
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This removes around 900 unnecessary clones, ranging from cloning a few
ints all the way to large data structures and images.
A lot of these were fixed using `cargo clippy --fix --workspace
--all-targets`, however it often breaks other lints and needs to be run
again. This was then followed up with some manual fixing.
I understand this is a large diff, but all the changes are pretty
trivial. Rust is doing some heavy lifting here for us. Once I get it up
to speed with main, I'd appreciate this getting merged rather sooner
than later.
Release Notes:
- N/A
This PR is one step in a series of refactors to prepare for having
"remote" projects that do not use SSH. The main use cases for this are
WSL and dev containers.
Release Notes:
- N/A
Closes#25744
Only setting changes and editor init determined whether to show
predictions, so glob patterns and toggles correctly disabled them. On
cursor changes we call `update_visible_edit_prediction`, but we weren’t
discarding predictions when the scope changed. This PR fixes that.
Release Notes:
- Fixed an issue where the `edit_predictions_disabled_in` setting was
ignored in some cases.
Highlight them as errors in the editor, and add a leading space when
sending them so users don't hit the odd behavior when sending these
commands to the SDK.
Release Notes:
- N/A
Closes#35932Closes#35933
I only intended to fix multi select in this, I accidentally drive-by
fixed the VIM issue as well. `replace_text_in_range` which I was using
before has two, to me unexpected, side-effects:
- it no-ops when input is disabled, which is the case in VIM's
Insert/Visual modes
- it takes the current selection into account, and does not just operate
on the given range (which I erroneously assumed before)
Now the code is using `buffer.edit` instead, which seems more lower
level, and does not have those side-effects. I was enthused to see that
it accepts a vec of edits, so I didn't have to calculate offsets for
following edits... until I also wanted to set selections, where I do
need to do it by hand. I'm still wondering if there is a simpler way to
do it, but for now it at least passes my muster
Release Notes:
- Added multiple selection support to UnwrapSyntaxNode action
- Fixed UnwrapSyntaxNode not working in VIM Insert/Visual modes
Prior to https://github.com/zed-industries/zed/pull/34564 as well as
https://github.com/zed-industries/zed/pull/26893, we would have cases
where editors would be scrollable even if `soft_wrap` was set to
`editor_width`. This has regressed and improved quite a few times back
and forth. The issue was only within the editor code, the code for the
wrap map was functioning and tested properly.
Hence, this PR adds two tests to the editor rendering code in an effort
to ensure that we maintain the current correct behavior.
Release Notes:
- N/A
Closes https://github.com/zed-industries/zed/issues/11780
While auto indentation is generally nice to have, there are cases where
it is currently just not good enough for some languages (e.g. Haskell)
or users just straight up do not want their editor to auto indent for
them. Hence, this PR adds the possibilty to disable auto indentation for
either all language or on a per-language basis. Manual invocation via
the `editor: auto indent` action will continue to work.
Also takes a similar approach as
https://github.com/zed-industries/zed/pull/31569 to ensure performance
is fine for larger multicursor edits.
Release Notes:
- Added the possibility to configure auto indentation for all languages
and per language. Add `"auto_indent": false"` to your settings or
desired language to disable the feature.
Closes#36247
Fix a panic when padding inlay hints if the last character is a
multi-byte character. Regressed in
https://github.com/zed-industries/zed/pull/35786.
Release Notes:
- Fixed a crash that could occur when an inlay hint ended with `...`.
This adds a context menu to buffer headers mimicking that of pane tabs,
notably being able to copy the relative and absolute paths of the buffer
as well as opening a terminal in the parent.
Confusingly prior to this right clicking a buffer header used to open
the context menu of the underlying editor.
Release Notes:
- Added context menu for buffer titles
- **WIP: reorganize dispositions**
- **Introduce a LocalToolchainStore trait and use it for LspAdapter
methods**
Closes#35782Closes#27331
Release Notes:
- Python: Improved propagation of a selected virtual environment into
the LSP configuration. This should the make all language-related
features such as Go to definition or Find all references more reliable.
---------
Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: Lukas Wirth <lukas@zed.dev>
Release Notes:
- Added an option for the status_bar.cursor_position_button. Setting to
`false` will hide the button. It defaults to `true`.
This builds off the recent work to hide the language selection button
(https://github.com/zed-industries/zed/pull/33977). I tried to follow
that pattern, and to pick a clear name for the option, but any
feedback/change is welcome.
---------
Co-authored-by: zumbalogy <3770982+zumbalogy@users.noreply.github.com>