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
Fix Helix `o`/`O` behavior when a selection is active.
This updates `InsertLineAbove` and `InsertLineBelow` to use the
selection bounds correctly for Helix selections, including line
selections whose end is represented at column 0 of the following line.
It also adds Helix select-mode keybindings for `o` and `O`, and adds
tests covering both line selections and selections created via `v`.
Closes#43210
Release Notes:
- helix: Fixed insert line above/below behavior when a full line is
selected
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
This extracts a `language_core` crate from the existing `language`
crate, and creates a `grammars` data crate. The goal is to separate
tree-sitter grammar infrastructure, language configuration, and LSP
adapter types from the heavier buffer/editor integration layer in
`language`.
## Motivation
The `language` crate pulls in `text`, `theme`, `settings`, `rpc`,
`task`, `fs`, `clock`, `sum_tree`, and `fuzzy` — all of which are needed
for buffer integration (`Buffer`, `SyntaxMap`, `Outline`,
`DiagnosticSet`) but not for grammar parsing or language configuration.
Extracting the core types lets downstream consumers depend on
`language_core` without pulling in the full integration stack.
## Dependency graph after extraction
```
language_core ← gpui, lsp, tree-sitter, util, collections
grammars ← language_core, rust_embed, tree-sitter-{rust,python,...}
language ← language_core, text, theme, settings, rpc, task, fs, ...
languages ← language, grammars
```
## What moved to `language_core`
- `Grammar`, `GrammarId`, and all query config/builder types
- `LanguageConfig`, `LanguageMatcher`, bracket/comment/indent config
types
- `HighlightMap`, `HighlightId` (theme-dependent free functions
`highlight_style` and `highlight_name` stay in `language`)
- `LanguageName`, `LanguageId`
- `LanguageQueries`, `QUERY_FILENAME_PREFIXES`
- `CodeLabel`, `CodeLabelBuilder`, `Symbol`
- `Diagnostic`, `DiagnosticSourceKind`
- `Toolchain`, `ToolchainScope`, `ToolchainList`, `ToolchainMetadata`
- `ManifestName`
- `SoftWrap`
- LSP data types: `BinaryStatus`, `ServerHealth`,
`LanguageServerStatusUpdate`, `PromptResponseContext`, `ToLspPosition`
## What stays in `language`
- `Buffer`, `BufferSnapshot`, `SyntaxMap`, `Outline`, `DiagnosticSet`,
`LanguageScope`
- `LspAdapter`, `CachedLspAdapter`, `LspAdapterDelegate` (reference
`Arc<Language>` and `WorktreeId`)
- `ToolchainLister`, `LanguageToolchainStore` (reference `task` and
`settings` types)
- `ManifestQuery`, `ManifestProvider`, `ManifestDelegate` (reference
`WorktreeId`)
- Parser/query cursor pools, `PLAIN_TEXT`, point conversion functions
## What the `grammars` crate provides
- Embedded `.scm` query files and `config.toml` files for all built-in
languages (via `rust_embed`)
- `load_queries(name)`, `load_config(name)`,
`load_config_for_feature(name, grammars_loaded)`, and `get_file(path)`
functions
- `native_grammars()` for tree-sitter grammar registration (behind
`load-grammars` feature)
## Pre-cleanup (also in this PR)
- Removed unused `Option<&Buffer>` from
`LspAdapter::process_diagnostics`
- Removed unused `&App` from `LspAdapter::retain_old_diagnostic`
- Removed `fs: &dyn Fs` from `ToolchainLister` trait methods
(`PythonToolchainProvider` captures `fs` at construction time instead)
- Moved `Diagnostic`/`DiagnosticSourceKind` out of `buffer.rs` into
their own module
## Backward compatibility
The `language` crate re-exports everything from `language_core`, so
existing `use language::Grammar` (etc.) continues to work unchanged. The
only downstream change required is importing `CodeLabelExt` where
`.fallback_for_completion()` is called on the now-foreign `CodeLabel`
type.
Release Notes:
- N/A
---------
Co-authored-by: Agus Zubiaga <agus@zed.dev>
Co-authored-by: Tom Houlé <tom@tomhoule.com>
Update vim and helix replace to repeat based on grapheme count instead of
byte length or Unicode scalar count.
This fixes cases where a single visible character is made up of multiple
bytes or scalars, such as decomposed characters like `e\u{301}` and emoji.
Closes#51772
Release Notes:
- Fixed vim/helix's replace action to take into consideration grapheme
count
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
* Update `Vim::register` to correctly re-activate when either `vim_mode`
or `helix_mode` are enabled, when they were previously disabled.
* Update `settings_ui::page_data::keymap_page` such that, when enabling
or disabling `vim_mode` or `helix_mode`, the other setting is
disabled, in case it is set. This ensures that only one mode is
enabled at a time, as it should be.
Closes#51704
Release Notes:
- Fixed switching between vim and helix mode needing multiple calls to
have an effect while an editor is already open
- Update Settings UI such that, enabling vim or helix mode, now disables
the other if it was previously active
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
* Add `editor::RewrapOptions::line_length` to, optionally, override the
line length used when rewrapping text.
* Update `editor::Editor::rewrap_impl` to prefer
`editor::RewrapOptions::line_length`, when set.
* Add a `line_length` field to the `vim::rewrap::Rewrap` action.
* Update the `:reflow` vim command with `vim::command::VimCommand::args`
so as to be able to parse the provided argument as `usize`, ensuring
that no effect is taken if the argument can't be parsed as such.
Release Notes:
- N/A
Add support for Helix's `:reflow` command when vim or helix mode is
enabled.
Release Notes:
- Add support for helix's `:reflow` command
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
Closes#51740
The multi-line cursor expansion operates off of byte offsets, instead of
character offsets, so multi-byte characters like the umlaut cause the
multi-line cursors to be weirdly offset. To fix we just convert the
expansion logic to rely on utf16 characters instead of bytes.
before behavior:
https://github.com/user-attachments/assets/320e24e9-0fdd-4d16-a9e8-ca17c9e21ff2
after behavior:
https://github.com/user-attachments/assets/c4f0334b-dffc-4530-91ee-577b4fab75dd
+ test to verify functionality.
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- editor: fixed multi-line cursor expansion dealing with multi-byte
characters.
---------
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
Closes#51693
Helix was unable to paste from the system clipboard, ex: `vim: paste`
would work but `helix: paste` would not work. Helix paste was silently
requiring the content it was going to paste to have selection metadata
exist, and just silently fail if it didn't, and the system clipboard
doesn't have that metadata. note: this is not necessarily for parity
with helix, as helix didn't seem to support this either in my testing,
but rather parity with the other parts of zed, editor mode and vim mode.
single-line paste:
https://github.com/user-attachments/assets/c8696032-d265-4025-9c4c-a8c35dfd2529
multi-line paste:
https://github.com/user-attachments/assets/4bf96033-e13d-4ec1-8a7e-8c56bbc12b94
I also added a new test verifying the behavior.
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- helix: fixed helix paste not pasting from system clipboard.
Save edited buffers before running a task
Introduces a new task field for configuring which buffers are saved. For
now, this defaults to saving all buffers, but in the future we could
have a global task template to configure this setting for dynamically
created tasks.
Needed for #10251.
Release Notes:
- Edited buffers are now saved before running a task. This can be
configured with the new "save" field in `tasks.json`.
---------
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
- Simplify and improve Windows clipboard handler.
- Fixed components that weren't handling multiple formats on the
clipboard properly.
Closes https://github.com/zed-industries/zed/issues/51278
Release Notes:
- windows: Fixed an issue where text copied from Office applications
couldn't be pasted into Zed.
All of the important changes are in
[`db.rs`](https://github.com/zed-industries/zed/pull/51809/changes#diff-2f644eab943bfa58feec29256281a3d9e8d4d7784cd34783e845af8beb15b16d).
Consider reading the commit log in order to review this work.
The DB crate's macro and API was changed to fix flakiness observed in
the MultiWorkspace tests when run locally. This flakiness was caused by
a shared `static LazyLock`, that caused concurrent test runs to interact
with the same underlying in-memory database. This flakiness wasn't
possible on CI due to it's usage of `cargo nextest`, whose
process-per-test approach masked this problem.
Essentially, I've changed the `static_connection` macro to remove the
static database variable and redone the internal model. Now, all
database types are thin wrappers around a generic `AppDatabase`. The
`AppDatabase` collects all of the individual table's migrations via the
`inventory` crate, and so only runs the migrations once on startup,
rather than a dozen times on startup.
The new API requires a `cx` so that we can replace the database returned
at runtime, rather than relying exclusively on a process-global
thread-local. However, we are still using a `static LazyLock` so that we
only need to take an `&App`, instead of an `&mut App`. These databases
types are `Clone + Send + Sync`, so you can easily capture-and-move the
database into background tasks and other places that don't have a `cx`.
For tests that require database isolation, it is now possible to set
their own database in init. See
[`workspace::init_test`](https://github.com/zed-industries/zed/pull/51809/changes#diff-041673bbd1947a35d45945636c0055429dfc8b5985faf93f8a8a960c9ad31e28R13610),
for the flakiness fix.
Best part, this change should be entirely compiler driven, so the Zed
agent was able to make the app-wide refactor easily.
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
---------
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
Ensure that the `vim::visual::Vim::visual_block_motion` method is called
when `scroll_editor` is called while in Visual Block mode. This fixes an
issue where, after getting into `Visual Block` mode, if the user used
`ctrl-d` or `ctrl-u` to scroll half of the page, the wrong selection
would be made and, if `shift-i` was used to start inserting at the start
of the line, a single cursor would be placed at the cursor position
where the selection was started, instead of one cursor per each of the
selected lines.
These changes ensure that we now match Neovim's behavior for the same
flow.
---------
Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
Co-authored-by: dino <dinojoaocosta@gmail.com>
Update Helix's handling of the following actions in order to ensure that
selections are created when using subword motions:
* `vim::NextSubwordStart`
* `vim::NextSubwordEnd`
* `vim::PreviousSubwordStart`
* `vim::PreviousSubwordEnd`
The handling of these motions was done by
`vim::helix::Vim::helix_move_and_collapse`, which simply moved the
cursor without doing any selection. This commit updates it to correctly
use both `vim::helix::Vim::helix_find_range_forward` and
`vim::helix::Vim::helix_find_range_backward`.
The added tests have been confirmed against Helix's behavior of the following commands:
* `move_next_sub_word_start`
* `move_prev_sub_word_start`
* `move_next_sub_word_end`
* `move_prev_sub_word_end`
Closes#41767
Release Notes:
- Fix subword motions in Helix mode to select traversed text
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Co-authored-by: dino <dinojoaocosta@gmail.com>
Fixes ZED-4YP
Sort and deduplicate anchor ranges in do_helix_select before passing
them to select_anchor_ranges. When the search wraps past the end of the
document back to the beginning, the new selection is at a lower offset
than the accumulated prior selections, producing unsorted anchors that
crash the rope cursor with 'cannot summarize backward'.
Release Notes:
- Fixed a panic in helix mode with search selecting wrapping around the
document end
When a command used an explicit register (e.g. `"_dd` or `"add`), the
subsequent dot repeat (`.`) was ignoring that register and using the
default instead.
Store the register at recording start in `recording_register_for_dot`,
persist it to `recorded_register_for_dot` when recording stops, and
restore it in `Vim::repeat` when no explicit register is supplied for
`.`. An explicit register on `.` (e.g. `"b.`) still takes precedence.
This commit also updates the dot-repeat logic to closely follow Neovim's
when using numbered registers, where each dot repeat increments the
register. For example, after using `"1p`, using `.` will repeat the
command using `"2p`, `"3p`, etc.
Closes#49867
Release Notes:
- Fixed vim's repeat . to preserve the register the recorded command
used
- Updated vim's repeat . to increment the recorded register when using
numbered registers
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
In Helix, selecting a line with `x` creates a selection from column 0 of
the current row to column 0 of the next row. The default
`InsertEndOfLine` uses the selection head (which is on the next row) to
find the line end, placing the cursor on the wrong line.
This commit introduces a new `HelixInsertEndOfLine`, mapped by default
to `shift-a` when Helix mode is enabled, that moves left from the head
first to land on the correct line.
Release Notes:
- Fixed `shift-a` in Helix select mode placing the cursor on the wrong
line after selecting with `x`
---------
Co-authored-by: SkandaBhat <9384046+SkandaBhat@users.noreply.github.com>
Co-authored-by: dino <dinojoaocosta@gmail.com>
https://github.com/zed-industries/zed/pull/42837 added the
`cursor_offset_on_selection` field, which displays the cursor *after*
the end of the selection unless a vim visual mode is enabled, in which
case it gets displayed *at* the end of the selection.
However, the real helix is effectively *always* in select mode, and will
always display the cursor at the end of the selection, whether that
selection is made via its visual mode, a movement key, or with the
mouse.
This makes it so that the helix mode setting is taken into account
regardless of the visual-ness of the vim mode in the `sync_vim_settings`
method.
I also considered simply moving `Mode::HelixNormal` up to the `true` arm
of the match in the `is_visual` method since helix is kinda *always* in
visual mode, but I figured that could have some unintended consequences
and chose to err on the side of caution.
Possibly related to #20121Closes#46998
Release Notes:
- Fixed the cursor offset in non-visual helix selections
Co-authored-by: Nils Koch <mail@nilskch.dev>
BufferEvent::Edited had no way to distinguish local edits from remote
(collaboration) edits. This caused edit prediction behavior to fire on
the guest's editor when the host made document changes.
Release Notes:
- Fixed edit predictions triggering on collaboration guests when the
host edits the document.
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
This will help with test times (in some cases), as nextest cannot figure
out whether a given rdep is actually an alive edge of the build graph
Closes #ISSUE
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
- [ ] 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:
- N/A
Fixes#42444
- Changed `accepts_text_input` on the editor to be more precise.
Previously, it returned `true` only in insert mode. Now it also returns
`true` when an operator is pending.
- On Windows, we disable the IME whenever there is no input handler
which `accepts_text_input`.
- How this improves Vim mode: in insert mode, the IME is enabled; in
normal mode, it is disabled (command keys are not intercepted); when an
operator is pending, the IME is re-enabled.
Release Notes:
- On Windows, the IME is disabled in Vim normal and visual modes.
* Add a dedicated `vim.yank.background` theme color for the yank
highlight, which was previously hardcoded to
`editor.document_highlight.read_background`.
* When a theme doesn't define `vim.yank.background`, it falls back to
`editor.document_highlight.read_background` for backwards
compatibility.
* The VS Code theme importer maps `editor.rangeHighlightBackground` to
this new color.
Release Notes:
- Added configurable `vim.yank.background` theme color for vim yank
background highlight
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
Ensure that editing one tag in a linked pair correctly mirrors the change
to the other tag for Vim delete/change/substitute commands, visual
mode operations, and the standard editor delete action.
Extract a `LinkedEdits` struct to deduplicate linked edit collection and
application across `handle_input`, `replace_selections`, `do_completion`,
`backspace`, and `delete`. Introduce `linked_edits_for_selections` as a
shared helper for building linked edits from the current selections.
Closes#35941
Release Notes:
- Fixed linked edits for delete/change/substitute commands so tag pairs
stay in sync.
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
When clipboard data was produced by the editor's copy/cut with multiple
entire-line selections, vim's paste would panic with `byte index N is
out of bounds`.
The editor's `do_copy` and `cut_common` skip the `\n` separator between
clipboard selections when the previous selection was an entire-line
selection (because the text already ends with `\n`). However, vim's
paste code unconditionally did `start_offset = end_offset + 1`, always
assuming a `\n` separator exists between every pair of selections. This
caused the accumulated offset to exceed the text length, resulting in a
string slicing panic.
The fix checks `clipboard_selection.is_entire_line` to decide whether to
skip the separator, matching the behavior of the editor's own `do_paste`
method. The same fix is applied to both the vim and helix paste
implementations.
Release Notes:
- Fixed a crash when using vim paste on clipboard data copied with the
editor's copy command containing multiple entire-line selections.
Replaces a bunch of `impl FnMut` parameters with `&mut dyn FnMut` for
functions where this is the sole generic parameter.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Reverts the editor's paragraph navigation behavior that was changed in
#47734. Whitespace-only lines are now treated as paragraph boundaries
again for non-vim mode users.
Vim mode retains its own implementation where only truly empty lines
are paragraph boundaries.
Release Notes:
- Fixed editor paragraph navigation to treat whitespace-only lines as
paragraph boundaries again
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: dino <dinojoaocosta@gmail.com>
Add workspace::CloseItemInAllPanes action that closes the active
item's buffer in every pane where it's open, matching Vim's `:bdelete`
semantics. Pane layout is preserved, only the buffer is removed.
`:bd` respects pinned tabs, `:bd!` overrides them and skips save.
Also refactors the tab switcher's close button to use the new
`close_items_with_project_path` method, removing duplicated logic.
Release Notes:
- Vim: `:bd` (`:bdelete`) now closes the file in all panes where it's
open
- Added `workspace::CloseItemInAllPanes` action to close a file across
all panes
Co-authored-by: David Baldwin <baldwindavid@gmail.com>
Release Notes:
- Added agent panel restoration. Now restarting your editor won't cause
your thread to be forgotten.
---------
Co-authored-by: Anthony Eid <56899983+Anthony-Eid@users.noreply.github.com>
Co-authored-by: Eric Holk <eric@zed.dev>
Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
Co-authored-by: Anthony Eid <anthony@zed.dev>
Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
Co-authored-by: Cameron Mcloughlin <cameron.studdstreet@gmail.com>
Add `workspace::CloseItemInAllPanes` action that closes the active
item's buffer in every pane where it's open, matching Vim's `:bdelete`
semantics. Pane layout is preserved, only the buffer is removed.
`:bd` respects pinned tabs, `:bd!` overrides them and skips save.
Also refactors the tab switcher's close button to use the new
`close_items_with_project_path` method, removing duplicated logic.
Release Notes:
- Vim: `:bd` (`:bdelete`) now closes the file in all panes where it's
open
- Added `workspace::CloseItemInAllPanes` action to close a file across
all panes
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
When using `$` to move to the end of line (`vim::EndOfLine`), the
`vim::motion::Motion.move_point` method checks whether the new point,
that is, the point after the motion is applied is different from the
point that was passed as a method argument. If the point is not
different, the point and selection goals are only updated if
`vim::motion::Motion.infallible` returns true for the motion in
question.
In short, this means that, if the cursor was already at the end of the
line, and it got there using `vim::Right`, for example, the selection
goal wouldn't actually be set to
`SelectionGoal::HorizontalPosition(f64::INFINITY)`, so when the cursor
was moved to a shorter line, it wouldn't be set at the end of that line,
even though `$` had been used.
This commit updates `vim::motion::Motion.infallible` to ensure that, for
`vim::motion::Motion::EndOfLine`, it returns `true`, so that the
selection goal is always updated, regardless of whether the cursor is
already at the end of the line.
Closes#48855
- [X] Tests or screenshots needed?
- [X] Code Reviewed
- [X] Manual QA
Release Notes:
- vim: Fixed `$` not sticking to end-of-line on vertical motions
(`j`/`k`) when the cursor was already at the end of the line via `l` or
arrow keys
The multi workspace refactor **completely** broke the Vim mode, saving
is not possible, and various other actions. This PR fixes this
- [X] Code Reviewed
- [X] Manual QA
Release Notes:
- N/A
It's happeningggggg
Release Notes:
- Changed the Agent Panel so that the Active Thread is restored on
restart.
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-authored-by: Anthony Eid <anthony@zed.dev>
Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
Co-authored-by: Richard Feldman <richard@zed.dev>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Release Notes:
- Fixed `HelixSelectLine` with an empty first line and a pre-existing
selection.
---------
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
Co-authored-by: Lena Falk <lena@zed.dev>
`find_target()` failed to match numbers followed by a dot and a
non-digit (e.g. `1. item`), because the dot unconditionally reset
the scan state, discarding the number. Additionally, numbers at the
start of non-first lines were missed because the backward scan
stopped on the preceding newline and the forward scan immediately
broke on it.
Closes#47761
Release Notes:
- Fixed vim increment (`ctrl-a`) and decrement (`ctrl-x`) not working on Markdown ordered list markers like `1.`, `2.`, etc.
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: dino <dinojoaocosta@gmail.com>
These changes update subword motions in order to also take `$` and `=`
into consideration as stopping punctuation, improving the subword
motions for certain languages where `$` and `=` are commonly used, like
PHP, for variables and assignments.
Closes#48267
Release Notes:
- Improved Vim's subword motions to stop at `$` and `=` characters
Part of #7450
Big thanks to @macmv for pushing this forwards so much!
Rebased version of https://github.com/zed-industries/zed/pull/39539 as
working on an in-org branch simplifies a lot of things for us)
Release Notes:
- Added LSP semantic tokens highlighting support
---------
Co-authored-by: Neil Macneale V <neil.macneale.v@gmail.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.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>
- 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>