Commit graph

319 commits

Author SHA1 Message Date
Piotr Osiewicz
cc279a46fa
editor: Improve find_matches and replace_all perf (#51941)
Helps with https://github.com/zed-industries/zed/issues/38927

- **editor: Add a benchmark for find/replace**
- **text: batch fragment insertions before turning them into a SumTree**

## Context

<!-- 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. -->

## How to Review

<!-- Help reviewers focus their attention:
- For small PRs: note what to focus on (e.g., "error handling in
foo.rs")
- For large PRs (>400 LOC): provide a guided tour — numbered list of
files/commits to read in order. (The `large-pr` label is applied
automatically.)
     - See the review process guidelines for comment conventions -->

## 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
- [ ] 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:

- Improved performance of "Replace All" in buffer search

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-05-06 09:28:05 +00:00
Cole Miller
2a15bf630d
Require multibuffer excerpts to be ordered and nonoverlapping (#52364)
TODO:
- [x] merge main
- [x] nonshrinking `set_excerpts_for_path`
- [x] Test-drive potential problem areas in the app
- [x] prepare cloud side
- [x] test collaboration
- [ ] docstrings
- [ ] ???

## Context

### Background

Currently, a multibuffer consists of an arbitrary list of
anchor-delimited excerpts from individual buffers. Excerpt ranges for a
fixed buffer are permitted to overlap, and can appear in any order in
the multibuffer, possibly separated by excerpts from other buffers.
However, in practice all code that constructs multibuffers does so using
the APIs defined in the `path_key` submodule of the `multi_buffer` crate
(`set_excerpts_for_path` etc.) If you only use these APIs, the resulting
multibuffer will maintain the following invariants:

- All excerpts for the same buffer appear contiguously in the
multibuffer
- Excerpts for the same buffer cannot overlap
- Excerpts for the same buffer appear in order
- The placement of the excerpts for a specific buffer in the multibuffer
are determined by the `PathKey` passed to `set_excerpts_for_path`. There
is exactly one `PathKey` per buffer in the multibuffer

### Purpose of this PR

This PR changes the multibuffer so that the invariants maintained by the
`path_key` APIs *always* hold. It's no longer possible to construct a
multibuffer with overlapping excerpts, etc. The APIs that permitted
this, like `insert_excerpts_with_ids_after`, have been removed in favor
of the `path_key` suite.

The main upshot of this is that given a `text::Anchor` and a
multibuffer, it's possible to efficiently figure out the unique excerpt
that includes that anchor, if any:

```
impl MultiBufferSnapshot {
    fn buffer_anchor_to_anchor(&self, anchor: text::Anchor) -> Option<multi_buffer::Anchor>;
}
```

And in the other direction, given a `multi_buffer::Anchor`, we can look
at its `text::Anchor` to locate the excerpt that contains it. That means
we don't need an `ExcerptId` to create or resolve
`multi_buffer::Anchor`, and in fact we can delete `ExcerptId` entirely,
so that excerpts no longer have any identity outside their
`Range<text::Anchor>`.

There are a large number of changes to `editor` and other downstream
crates as a result of removing `ExcerptId` and multibuffer APIs that
assumed it.

### Other changes

There are some other improvements that are not immediate consequences of
that big change, but helped make it smoother. Notably:

- The `buffer_id` field of `text::Anchor` is no longer optional.
`text::Anchor::{MIN, MAX}` have been removed in favor of
`min_for_buffer`, etc.
- `multi_buffer::Anchor` is now a three-variant enum (inlined slightly):

```
enum Anchor {
    Min,
    Excerpt {
        text_anchor: text::Anchor,
        path_key_index: PathKeyIndex,
        diff_base_anchor: Option<text::Anchor>,
    },
    Max,
}
```

That means it's no longer possible to unconditionally access the
`text_anchor` field, which is good because most of the places that were
doing that were buggy for min/max! Instead, we have a new API that
correctly resolves min/max to the start of the first excerpt or the end
of the last excerpt:


```
impl MultiBufferSnapshot {
    fn anchor_to_buffer_anchor(&self, anchor: multi_buffer::Anchor) -> Option<text::Anchor>;
}
```
- `MultiBufferExcerpt` has been removed in favor of a new
`map_excerpt_ranges` API directly on `MultiBufferSnapshot`.

## 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:

- N/A

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
Co-authored-by: Conrad <conrad@zed.dev>
2026-04-01 17:25:32 +00:00
Lukas Wirth
8cbcadf196
Make paste a separate undo transaction from preceding edits (#52003)
When undoing a paste, it is really confusing when that actually also
removes what was type right before the paste if the paste happened fast
enough after.

Release Notes:

- Fixed undoing a paste sometimes also undoing edits right before the
paste
2026-03-30 07:17:02 +00:00
Max Brunsfeld
c1cbea10e9
Fix crash in apply text buffer operations found when opening a channel notes (#51978)
To do

* [x] turn the operations from collab into a failing test
* [x] fix the crash
* [ ] turn the huge set of operations into a succinct test that can be
checked in on main

Release Notes:

- N/A

---------

Co-authored-by: Ben Kunkle <ben@zed.dev>
2026-03-19 16:41:53 -07:00
loadingalias
e5bb2c6790
Fix non-ASCII path:line:column navigation (#51238)
Closes #43329

## Summary
This fixes `path:line:column` navigation for files containing non-ASCII
text.

Before this change, open path flows were passing the external column
directly into `go_to_singleton_buffer_point`. That happened to work for
ASCII, but it was wrong for Unicode because external columns are
user-visible character positions while the editor buffer stores columns
as UTF-8 byte offsets.

This PR adds a shared text layer conversion for external row/column
coordinates and uses it in the affected open-path flows:
 - file finder navigation
 - recent project remote connection navigation
 - recent project remote server navigation

It also adds regression coverage for the Unicode case that originally
failed.

As a small - necessary - prerequisite, this also adds
`remote_connection` test support to `file_finder`'s dev-deps so the
local regression test can build and run on this branch. That follows the
same feature mismatch pattern previously fixed in #48280. I wasn't able
to locally verify the tests/etc. w/o the addition... so I've rolled it
into this PR. Tests are green.

The earlier attempt in #47093 was headed in the right direction, but it
did not land and did not include the final regression coverage requested
in review.

## Verification
 - `cargo fmt --all -- --check`
 - `./script/clippy -p text`
 - `./script/clippy -p file_finder`
 - `./script/clippy -p recent_projects`
 - `cargo test -p file_finder --lib --no-run`
- `cargo test -p file_finder
file_finder_tests::test_row_column_numbers_query_inside_file -- --exact`
- `cargo test -p file_finder
file_finder_tests::test_row_column_numbers_query_inside_unicode_file --
--exact`
- `cargo test -p text
tests::test_point_for_row_and_column_from_external_source -- --exact`

## Manual

I reproduced locally on my machine (macOS) w/ a stateless launch using a
Unicode file (Cyrillic)

Before:
 - `:1:5` landed too far left
 - `:1:10` landed around the 4th visible Cyrillic character

After:
 - `:1:5` lands after 4 visible characters / before the 5th
 - `:1:10` lands after 9 visible characters / before the 10th

Release Notes:
- Fixed `path:line:column` navigation so non-ASCII columns land on the
correct character.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-03-16 15:35:59 +00:00
Cole Miller
2d0bd7cd04
Add more verbosity for panic inside summaries_for_anchors_with_payloads (#50940)
We are seeing the timestamp comparison fail in an unexpected way, e.g.
https://zed-dev.sentry.io/issues/7293482758/events/c7f7eab3f8f2463f879d4889a80d623e,
where it seems like `text::Anchor::is_max` should be returning true but
it apparently isn't. Add some more information when this panic happens
to understand what's going on.

Release Notes:

- N/A

Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
2026-03-06 15:03:21 +00:00
Lukas Wirth
21bd74a0fb
text: Narrow insertion-relative offsets from usize to u32 (#49801)
Reduces memory usage of `InsertionSlice` from 32 to 24 bytes, `Fragment`
from 120 to 96 bytes by narrowing offsets that are relative to
individual insertion operations from `usize` to `u32`. These offsets are
bounded by the size of a single insertion, not the total buffer size, so
`u32` is sufficient.

To prevent any single insertion from exceeding `u32::MAX` bytes, both
`Buffer::new_normalized` and `apply_local_edit`/`apply_remote_edit` now
split large text insertions into multiple fragments via
`push_fragments_for_insertion`.

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2026-02-25 08:12:04 +01:00
Lukas Wirth
b5eeeb98e4
agent_ui: Avoid querying OnboardingUpsell in prepaint (#49963)
This hits the sqlite database unnecessarily

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2026-02-24 09:24:38 +00:00
Lukas Wirth
ea0c55b303
text: Swap anchor_range_between and anchor_range_around (#49888)
These functions had their names swapped accidentally

Follow up to https://github.com/zed-industries/zed/pull/49618

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2026-02-23 14:07:04 +00:00
Marco Mihai Condrache
9b0cb4ec20
text: Store fragment's deletions on stack (#49726)
Helps #38927

- In the common case, each fragment has at most one deletion, so we can
skip the heap allocation
- SmallVec is smaller than an empty HashSet
- Makes cloning cheaper
- From my analysis of the code it's not possible to have duplicate ticks
(I may be wrong tho)

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
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)

Release Notes:

- N/A
2026-02-20 16:29:09 +00:00
Lukas Wirth
d9ece42cf5
text: Inline text::Anchor's timestamp field, shrinking its size (#49703)
This shrinks the size of `text::Anchor` from 32 bytes to 24 and
`multi_buffer::Anchor` from 72 bytes to 56

Release Notes:

- Improved the memory usage of Zed a bit
2026-02-20 10:17:22 +00:00
Lukas Wirth
037add06e4
editor: Fix bracket colorization discoloring pure deletion diff hunks (#49618)
Release Notes:

- N/A *or* Added/Fixed/Improved ...

Co-authored by: Cole Miller <cole@zed.dev>
2026-02-19 17:34:26 +00:00
Cole Miller
930f484fe4
git: Follow-up fixes for custom blocks in the side-by-side diff (#48747)
- Ensure that both sides are passed the appropriate companion data to
preserve spacers when syncing
- Remove companion handling in codepaths related to range folding, since
this isn't supported in the side-by-side diff
- Move handling of buffer folding into the block map
- Rework `set_companion` to handle both `DisplayMap`s at once
- DRY some code around block map syncing in the `DisplayMap`

TODO:

- [x] diagnose and fix issue that causes balancing blocks not to render
properly when they are adjacent to spacers (e.g. merge conflict buttons)
- [x] clear balancing blocks when clearing companion
- [x] additional tests: interaction between spacers and balancing
blocks, resizing

Release Notes:

- N/A
2026-02-08 20:10:52 -05:00
Lukas Wirth
74746aa974
multi_buffer: Optimize a bunch of things (#48519)
Release Notes:

- N/A *or* Added/Fixed/Improved ...

---------

Co-authored-by: Cole Miller <cole@zed.dev>
2026-02-05 20:10:02 +00:00
Lukas Wirth
723f683dda
text: Actually short circuit anchored_edits_since_in_range (#48486)
When the version is the same we used to still seek through the
underlying fragment sumtree despite having nothing to return. This has a
lot of unnecessary overhead.

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2026-02-05 15:57:11 +00:00
Lukas Wirth
5d2feaa144
editor: Implement semantic highlighting (#46356)
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>
2026-02-04 17:37:13 +00:00
Cole Miller
8bf3b4fece
git: Refactor buffer_diff point translation APIs for more efficient side-by-side diff syncing (#48237)
The side-by-side diff heavily relies on a primitive from `buffer_diff`
that converts a point on one side of the diff to a range of points on
the other side. The way this primitive is set up on main is pretty
naive--every time we call `points_to_base_text_points` (or
`base_text_points_to_points`), we need to iterate over all hunks in the
diff. That's particularly bad for the case of constructing a new
side-by-side diff starting from a multibuffer, because we call those
APIs once per excerpt, and the number of excerpts is ~equal to the
number of hunks.

This PR changes the point translation APIs exposed by `buffer_diff` to
make it easier to use them efficiently in `editor`. The new shape is a
pair of functions that return a patch that can be used to translate from
the main buffer to the base text or vice versa. When syncing edits
through the block map that touch several excerpts for the same buffer,
we can reuse this patch for excerpts after the first--so when building a
new side-by-side diff, we'll iterate over each hunk just once.

The shape of the new APIs also sets us up to scale down to cases like
editing on the right-hand side of the diff: we can pass in a point range
and give them permission to return an approximate patch that's only
guaranteed to give the correct results when used with points in that
range. For edits that only affect one excerpt, and given how the project
diff is set up, that should allow us to skip iterating over most of the
hunks in a buffer.

Release Notes:

- N/A

---------

Co-authored-by: cameron <cameron.studdstreet@gmail.com>
2026-02-03 22:18:59 -05:00
Jordi Villar
376e958569
Fix inverted char boundary check causing invalid offsets (#47112)
The logic in `anchor_at_offset` and `to_offset` seems inverted when
checking character boundaries. `assert_char_boundary` returns `true`
when the offset IS valid, but the code was adjusting offsets when the
function returned `true` (valid) instead of `false` (invalid).

Release Notes:

- N/A
2026-01-19 09:08:45 +01:00
Lukas Wirth
d092f3a41b
text: Speed up offset_for_anchor and fragment_id_for_anchor conversions (#46989)
And most importantly, speed `Anchor::cmp` by doing so.

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2026-01-16 15:23:57 +00:00
Cole Miller
554382a87e
git: Rework side-by-side diff to use distinct buffers for the left-hand side (#44838)
This PR reworks the (still feature-gated) side-by-side diff view to use
a different approach to representing the multibuffers on the left- and
right-hand sides.

Previously, these two multibuffers used identical sets of buffers and
excerpts, and were made to behave differently by adding a new knob to
the multibuffer controlling how diffs are displayed. Specifically, the
left-hand side multibuffer would filter out the added range of each hunk
from the excerpts using a new `FilteredInsertedHunk` diff transform, and
the right-hand side would simply not show the deleted sides of expanded
hunks. This approach has some problems:

- Line numbers, and actions that navigate by line number, behaved
incorrectly for the left-hand side.
- Syntax highlighting and other features that use the buffer syntax tree
also behaved incorrectly for the left-hand side.

In this PR, we've switched to using independent buffers to build the
left-hand side. These buffers are constructed using the base texts for
the corresponding diffs, and their lifecycle is managed by `BufferDiff`.
The red "deleted" regions on the left-hand side are represented by
`BufferContent` diff transforms, not `DeletedHunk` transforms. This
means each excerpt on the left represents a contiguous slice of a single
buffer, which fixes the above issues by construction.

The tradeoff with this new approach is that we now have to manually
synchronize excerpt ranges from the right side to the left, which we do
using `BufferDiffSnapshot::row_to_base_text_row`.

Release Notes:

- N/A

---------

Co-authored-by: cameron <cameron.studdstreet@gmail.com>
Co-authored-by: HactarCE <6060305+HactarCE@users.noreply.github.com>
Co-authored-by: Miguel Raz Guzmán Macedo <miguel@zed.dev>
Co-authored-by: Anthony <anthony@zed.dev>
Co-authored-by: Cameron <cameron@zed.dev>
2025-12-31 20:02:45 -05:00
Piotr Osiewicz
47c30b6da7
git: Revert "Ignore whitespace in git blame invocation" (#44648)
Reverts zed-industries/zed#35960
cc @cole-miller

---------

Co-authored-by: Cole Miller <cole@zed.dev>
2025-12-12 14:28:25 +01:00
Lukas Wirth
18d344e118
language: Make TreeSitterData only shared between snapshots of the same version (#44198)
Currently we have a single cache for this data shared between all
snapshots which is incorrect, as we might update the cache to a new
version while having old snapshots around which then may try to access
new data with old offsets/rows.

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-12-12 14:15:50 +01:00
Lukas Wirth
511e51c80e
text: Replace some more release panics with graceful fallbacks (#44542)
Fixes ZED-3P7

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-12-10 13:01:31 +00:00
Max Brunsfeld
76167109db
Add experimental LSP-based context retrieval system for edit prediction (#44036)
To do

* [x] Default to no context retrieval. Allow opting in to LSP-based
retrieval via a setting (for users in `zeta2` feature flag)
* [x] Feed this context to models when enabled
* [x] Make the zeta2 context view work well with LSP retrieval
* [x] Add a UI for the setting (for feature-flagged users)
* [x] Ensure Zeta CLI `context` command is usable

---

* [ ] Filter out LSP definitions that are too large / entire files (e.g.
modules)
* [ ] Introduce timeouts
* [ ] Test with other LSPs
* [ ] Figure out hangs

Release Notes:

- N/A

---------

Co-authored-by: Ben Kunkle <ben@zed.dev>
Co-authored-by: Agus Zubiaga <agus@zed.dev>
2025-12-04 12:48:39 -08:00
Lukas Wirth
61ae59708d
text: Downgrade some more offset panics to error logs (#43925)
Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-12-01 18:04:01 +00:00
Lukas Wirth
fafe1afa61
multi_buffer: Remove redundant buffer id field (#43459)
It is easy for us to get the two fields out of sync causing weird
problems, there is no reason to have both here so.

Release Notes:

- N/A *or* Added/Fixed/Improved ...

Co-authored by: Antonio Scandurra <antonio@zed.dev>
2025-11-25 17:13:16 +01:00
Lukas Wirth
f8965317c3
multi_buffer: Fix up some anchor checks (#43454)
Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-11-25 13:41:19 +00:00
Lukas Wirth
28ef7455f0
gpui: #[inline] some trivial functions (#43189)
These appear in a lot of stacktraces (especially on windows) despite
them being plain forwarding calls.

Also removes some intermediate calls within gpui that will only turn
into more unnecessary compiler work.

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-11-20 19:54:47 +00:00
Lukas Wirth
c98b2d6944
multi_buffer: Typed MultiBufferOffset (#42707)
This PR introduces a new `MultiBufferOffset` new type wrapping size. The
goal of this is to make it clear at the type level when we are
interacting with offsets of a multi buffer versus offsets of a language
/ text buffer. This improves readability of things quite a bit by making
it clear what kind of offsets one is working with while also reducing
accidental bugs by using the wrong kin of offset for the wrong API.

This PR also uncovered two minor bugs due to that.

Does not yet introduce the MultiBufferPoint equivalent, that is for a
follow up PR.

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-11-19 22:00:58 +00:00
Lukas Wirth
6bea23e990
text: Temporarily remove assert_char_boundary panics (#42919)
As discussed in the first responders meeting. We have collected a lot of
backtraces from these, but it's not quite clear yet what causes this.
Removing these should ideally make things a bit more stable even if we
may run into panics later one when the faulty anchor is used still.

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-11-17 22:20:45 +00:00
Piotr Osiewicz
6b239c3a9a
Bump Rust to 1.91.1 (#42561)
Release Notes:

- N/A

---------

Co-authored-by: Julia Ryan <juliaryan3.14@gmail.com>
2025-11-12 20:27:04 +00:00
Lukas Wirth
32047bef93
text: Improve panic messages with more information (#42072)
Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-11-06 09:16:45 +00:00
Lukas Wirth
3e7b8efb98
editor: Newtype WrapRow (#41843)
Makes a better distinction between `WrapRow` and `BlockRow`

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-11-04 08:48:38 +00:00
Lukas Wirth
5fc54986c7
Revert "sum_tree: Replace rayon with futures (#41586) (#41846)
This causes the background executor to hang

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-11-03 19:25:15 +00:00
Lukas Wirth
4e6a562efe
editor: Fix refresh_linked_ranges panics due to old snapshot use (#41657)
Fixes ZED-29Z

Release Notes:

- Fixed panic in `refresh_linked_ranges`
2025-10-31 17:39:55 +01:00
Lukas Wirth
f2ce06c7b0
sum_tree: Replace rayon with futures (#41586)
Release Notes:

- N/A *or* Added/Fixed/Improved ...

Co-authored by: Kate <kate@zed.dev>
2025-10-31 10:39:01 +00:00
Kirill Bulatov
1b6cde7032
Revert "Fix ESLint linebreak-style errors by preserving line endings in LSP communication (#38773)" (#41355)
This reverts commit 435eab6896.

This caused format on save to scroll down to bottom instead of keeping
the position.

Release Notes:

- N/A
2025-10-28 08:45:02 +00:00
Lukas Wirth
2471ae451c
Pre-initialize global rayon threadpool (#41226)
We only use it a handful of times and the default amount of threads
(logical cpu core number) its spawns is overkill for this. This also
gives the threads names oppose to being labeled `<unknown>`

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-10-26 12:44:34 +00:00
Devdatta Talele
435eab6896
Fix ESLint linebreak-style errors by preserving line endings in LSP communication (#38773)
Closes https://github.com/zed-industries/zed/issues/38453

Current `Buffer` API only allows getting buffer text with `\n` line
breaks — even if the `\r\n` was used in the original file's text.

This it not correct in certain cases like LSP formatting, where language
servers need to have original document context for e.g. formatting
purposes.

Added new `Buffer` API, replaced all buffer LSP registration places with
the new one and added more tests.

Release Notes: 

- Fixed ESLint linebreak-style errors by preserving line endings in LSP
communication

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2025-10-23 19:11:48 +00:00
Lukas Wirth
6aaf19f276
multi_buffer: Split multi_buffer into more modules (#41033)
There are a of separate APIs in this, partially interleaved making it
difficult to grasp.

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-10-23 17:57:52 +00:00
Smit Barmase
10b9ae5e44
multi_buffer: Assert char boundary for panic due to point_to_buffer_offset (#40777)
In an attempt to figure out what's wrong with `point_to_buffer_offset`
for crash https://github.com/zed-industries/zed/issues/40453. We want to
know which branch among these two is the bad one.

Release Notes:

- N/A

Co-authored-by: Lukas Wirth <lukas@zed.dev>
2025-10-21 19:01:35 +05:30
kitt
f7a0971d2b
Add line endings indicator in status bar (#39609)
Closes #5294

This PR adds a line ending indicator to the status bar, hidden by
default as discussed in
https://github.com/zed-industries/zed/issues/5294.

### Changes

- 8b063a22d8700bed9c93989b9e0f6a064b2e86cf add the indicator and
`status_bar.line_endings_button` setting.

- ~~9926237b709dd4e25ce58d558fd385d63b405f3b changes
`status_bar.line_endings_button` from a boolean to an enum:~~
  <details> <summary> show details </summary>

   - `always`     Always show line endings indicator.
- `non_native` Indicate when line endings do not match the current
platform.
   - `lf_only`    Indicate when using unix-style (LF) line endings only.
- `crlf_only` Indicate when using windows-style (CRLF) line endings
only.
   - `never`      Do not show line endings indicator.
   
I know this many options might be overdoing it, but I was torn between
the pleasant default of `non_native` and the simplicity of `lf_only` /
`crlf_only`.

My thinking was if one is developing on a project which exclusively uses
one line-ending style or the other, it would be nice to be able to
configure no-indicator-in-the-happy-case behavior regardless of the
platform zed is running on. But I'm not really familiar with any
projects that use exclusively CRLF line endings in practice. Is this a
scenario worth supporting or just something I dreamed up?

   </details>

- 01174191e4cf337069e7a31b0f0432ae94c52515 rename the action context for
`line ending: Toggle` -> `line ending selector: Toggle`.
When running the action in the command palette with the old name I felt
surprised to be greeted with an additional menu, with the new name it
feels more predictable (plus now it matches
`language_selector::Toggle`!)

### Future work

Hidden status bar items still get padding, creating inconsistent spacing
(and it kind of stands out where I placed the line-endings button):

<img alt="the gap after the indicator is larger than for other buttons"
src="https://github.com/user-attachments/assets/24a346d4-3ff6-4f7f-bd87-64d453c2441a"
/>

I started a new follow-up PR to address that:
https://github.com/zed-industries/zed/pull/39992

Release Notes:

- Added line ending indicator to the status bar (disabled by default;
enabled by setting `status_bar.line_endings_button` to `true`)
2025-10-20 15:24:41 -06:00
Lukas Wirth
d8f4293ac3
sum_tree: Implement recursive Sumtree::find, use it over Cursor::seek if possible (#40700)
Reduces peak stack usage in these functions and should generally be a
bit performant.

Display map benchmark results
```
To tab point/to_tab_point/1024
                        time:   [531.40 ns 532.10 ns 532.97 ns]
                        change: [-2.1824% -2.0054% -1.8125%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 1 outliers among 100 measurements (1.00%)
  1 (1.00%) high severe

To fold point/to_fold_point/1024
                        time:   [530.81 ns 531.30 ns 531.80 ns]
                        change: [-2.0295% -1.9054% -1.7716%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 3 outliers among 100 measurements (3.00%)
  2 (2.00%) high mild
  1 (1.00%) high severe
```

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-10-20 17:20:09 +00:00
Lukas Wirth
43a9368dff
clock: Cleanup ReplicaId, Lamport and Global (#40600)
- Notable change is the use of a newtype for `ReplicaId`
- Fixes `WorktreeStore::create_remote_worktree` creating a remote
worktree with the local replica id, though this is not currently used
- Fixes observing the `Agent` (that is following the agent) causing
global clocks to allocate 65535 elements
- Shrinks the size of `Global` a bit. In a local or non-collab remote
session it won't ever allocate still.

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-10-20 13:26:20 +02:00
Lukas Wirth
27dcdb5841
multi_buffer: Reduce RefCell::borrow_mut calls to the bare minimum (#40522)
Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-10-17 18:17:34 +00:00
Lukas Wirth
85c2dc909d
rope: Improve panic message for out of bounds anchor_at_offset (#40256)
Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-10-15 14:36:58 +00:00
Piotr Osiewicz
d359a814f8
editor: Represent scroll offset with more precision (#39367)
Closes #5355

Release Notes:

- Fixed rendering glitches with files with more than 16 million lines
(that occured due to floating number rounding errors).

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2025-10-02 23:04:31 +02:00
Lukas Wirth
f2efe78feb
editor: Shrink size of Inlay slightly (#39089)
And some other smaller cleanup things I noticed while reading through
some stuff

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-09-29 15:33:21 +02:00
Lukas Wirth
e1b57f00a0
sum_tree: Reduce Cursor size for contextless summary types (#38776)
This reduces the size of cursor by a usize when the summary does not
require a context making Cursor usages and constructions slightly more
efficient.

This change is a bit annoying though, as Rust has no means of
specializing, so this uses a `ContextlessSummary` trait with a blanket
impl while turning the `Context` into a GAT `Context<'a>`. This means
`Summary` implies are a bit more verbose now while contextless ones are
slimmer. It does come with the downside that the lifetime in the GAT is
always considered invariant, so some lifetime splitting occurred due to
that.


 ```
push/4096               time:   [352.65 µs 360.87 µs 367.80 µs]
                        thrpt:  [10.621 MiB/s 10.825 MiB/s 11.077 MiB/s]
                 change:
time: [-2.6633% -1.3640% -0.0561%] (p = 0.05 < 0.05)
                        thrpt:  [+0.0561% +1.3828% +2.7361%]
                        Change within noise threshold.
Found 16 outliers among 100 measurements (16.00%)
  7 (7.00%) low severe
  3 (3.00%) low mild
  2 (2.00%) high mild
  4 (4.00%) high severe
push/65536              time:   [1.2917 ms 1.2949 ms 1.2979 ms]
                        thrpt:  [48.156 MiB/s 48.267 MiB/s 48.387 MiB/s]
                 change:
time: [+1.4428% +1.9844% +2.5299%] (p = 0.00 < 0.05)
                        thrpt:  [-2.4675% -1.9458% -1.4223%]
                        Performance has regressed.
Found 3 outliers among 100 measurements (3.00%)
  1 (1.00%) low severe
  1 (1.00%) low mild
  1 (1.00%) high severe

append/4096             time:   [677.87 ns 678.87 ns 679.83 ns]
                        thrpt:  [5.6112 GiB/s 5.6192 GiB/s 5.6274 GiB/s]
                 change:
time: [-0.8924% -0.5017% -0.1705%] (p = 0.00 < 0.05)
                        thrpt:  [+0.1708% +0.5043% +0.9004%]
                        Change within noise threshold.
Found 2 outliers among 100 measurements (2.00%)
  1 (1.00%) low mild
  1 (1.00%) high mild
append/65536            time:   [9.3275 µs 9.3406 µs 9.3536 µs]
                        thrpt:  [6.5253 GiB/s 6.5344 GiB/s 6.5435 GiB/s]
                 change:
time: [+0.5409% +0.7215% +0.9054%] (p = 0.00 < 0.05)
                        thrpt:  [-0.8973% -0.7163% -0.5380%]
                        Change within noise threshold.

slice/4096              time:   [27.673 µs 27.791 µs 27.907 µs]
                        thrpt:  [139.97 MiB/s 140.56 MiB/s 141.16 MiB/s]
                 change:
time: [-1.1065% -0.6725% -0.2429%] (p = 0.00 < 0.05)
                        thrpt:  [+0.2435% +0.6770% +1.1189%]
                        Change within noise threshold.
Found 5 outliers among 100 measurements (5.00%)
  4 (4.00%) low mild
  1 (1.00%) high mild
slice/65536             time:   [507.55 µs 517.40 µs 535.60 µs]
                        thrpt:  [116.69 MiB/s 120.80 MiB/s 123.14 MiB/s]
                 change:
time: [-1.3489% +0.0599% +2.2591%] (p = 0.96 > 0.05)
                        thrpt:  [-2.2092% -0.0598% +1.3674%]
                        No change in performance detected.
Found 8 outliers among 100 measurements (8.00%)
  5 (5.00%) low mild
  2 (2.00%) high mild
  1 (1.00%) high severe

bytes_in_range/4096     time:   [3.3917 µs 3.4108 µs 3.4313 µs]
                        thrpt:  [1.1117 GiB/s 1.1184 GiB/s 1.1247 GiB/s]
                 change:
time: [-5.3466% -4.7193% -4.1262%] (p = 0.00 < 0.05)
                        thrpt:  [+4.3038% +4.9531% +5.6487%]
                        Performance has improved.
Found 6 outliers among 100 measurements (6.00%)
  1 (1.00%) low mild
  5 (5.00%) high mild
bytes_in_range/65536    time:   [88.175 µs 88.613 µs 89.111 µs]
                        thrpt:  [701.37 MiB/s 705.31 MiB/s 708.82 MiB/s]
                 change:
time: [-0.6935% +0.3769% +1.4655%] (p = 0.50 > 0.05)
                        thrpt:  [-1.4443% -0.3755% +0.6984%]
                        No change in performance detected.
Found 2 outliers among 100 measurements (2.00%)
  2 (2.00%) high mild

chars/4096              time:   [678.70 ns 680.38 ns 682.08 ns]
                        thrpt:  [5.5927 GiB/s 5.6067 GiB/s 5.6206 GiB/s]
                 change:
time: [-0.6969% -0.2755% +0.1485%] (p = 0.20 > 0.05)
                        thrpt:  [-0.1483% +0.2763% +0.7018%]
                        No change in performance detected.
Found 9 outliers among 100 measurements (9.00%)
  5 (5.00%) low mild
  4 (4.00%) high mild
chars/65536             time:   [12.720 µs 12.775 µs 12.830 µs]
                        thrpt:  [4.7573 GiB/s 4.7778 GiB/s 4.7983 GiB/s]
                 change:
time: [-0.6172% -0.1110% +0.4179%] (p = 0.68 > 0.05)
                        thrpt:  [-0.4162% +0.1112% +0.6211%]
                        No change in performance detected.
Found 2 outliers among 100 measurements (2.00%)
  1 (1.00%) low mild
  1 (1.00%) high mild

clip_point/4096         time:   [33.240 µs 33.310 µs 33.394 µs]
                        thrpt:  [116.98 MiB/s 117.27 MiB/s 117.52 MiB/s]
                 change:
time: [-2.8892% -2.6305% -2.3438%] (p = 0.00 < 0.05)
                        thrpt:  [+2.4000% +2.7015% +2.9751%]
                        Performance has improved.
Found 12 outliers among 100 measurements (12.00%)
  1 (1.00%) low mild
  4 (4.00%) high mild
  7 (7.00%) high severe
clip_point/65536        time:   [1.6531 ms 1.6586 ms 1.6640 ms]
                        thrpt:  [37.560 MiB/s 37.683 MiB/s 37.808 MiB/s]
                 change:
time: [-6.6381% -5.9395% -5.2680%] (p = 0.00 < 0.05)
                        thrpt:  [+5.5610% +6.3146% +7.1100%]
                        Performance has improved.
Found 7 outliers among 100 measurements (7.00%)
  1 (1.00%) low mild
  2 (2.00%) high mild
  4 (4.00%) high severe

point_to_offset/4096    time:   [11.586 µs 11.603 µs 11.621 µs]
                        thrpt:  [336.15 MiB/s 336.67 MiB/s 337.16 MiB/s]
                 change:
time: [-14.289% -14.111% -13.939%] (p = 0.00 < 0.05)
                        thrpt:  [+16.197% +16.429% +16.672%]
                        Performance has improved.
Found 12 outliers among 100 measurements (12.00%)
  3 (3.00%) low severe
  5 (5.00%) low mild
  4 (4.00%) high mild
point_to_offset/65536   time:   [527.74 µs 532.08 µs 536.51 µs]
                        thrpt:  [116.49 MiB/s 117.46 MiB/s 118.43 MiB/s]
                 change:
time: [-6.7825% -4.6235% -2.3533%] (p = 0.00 < 0.05)
                        thrpt:  [+2.4100% +4.8477% +7.2760%]
                        Performance has improved.
Found 8 outliers among 100 measurements (8.00%)
  4 (4.00%) high mild
  4 (4.00%) high severe

cursor/4096             time:   [16.154 µs 16.192 µs 16.232 µs]
                        thrpt:  [240.66 MiB/s 241.24 MiB/s 241.81 MiB/s]
                 change:
time: [-3.2536% -2.9145% -2.5526%] (p = 0.00 < 0.05)
                        thrpt:  [+2.6194% +3.0019% +3.3630%]
                        Performance has improved.
Found 5 outliers among 100 measurements (5.00%)
  1 (1.00%) low mild
  2 (2.00%) high mild
  2 (2.00%) high severe
cursor/65536            time:   [509.60 µs 511.24 µs 512.93 µs]
                        thrpt:  [121.85 MiB/s 122.25 MiB/s 122.65 MiB/s]
                 change:
time: [-7.3677% -6.6017% -5.7840%] (p = 0.00 < 0.05)
                        thrpt:  [+6.1391% +7.0683% +7.9537%]
                        Performance has improved.
Found 6 outliers among 100 measurements (6.00%)
  3 (3.00%) high mild
  3 (3.00%) high severe
```
Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-09-24 14:35:38 +02:00
Lukas Wirth
55dc9ff7ca
text: Implement Rope::clip_offset in terms of the new utf8 boundary methods (#38630)
Release Notes:

- N/A
2025-09-22 11:45:23 +00:00