Commit Graph

95 Commits

Author SHA1 Message Date
Lukas Wirth
b92b28314f Replace {floor/ceil}_char_boundary polyfills with std (#42599)
Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-11-13 08:11:18 +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
f2b539598e sum_tree: Spawn less tasks in SumTree::from_iter_async (#41793)
Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-11-03 10:02:31 +00: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
Lukas Wirth
360074effb rope: Prevent stack overflows by bumping rayon stack sizes (#41397)
Thread stacks in rust by default have 2 megabytes of stack which for
sumtrees (or ropes in this case) can easily be exceeded depending on the
workload.

Release Notes:

- Fixed stack overflows when constructing large ropes
2025-10-28 20:21:49 +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
Adam Richardson
370d4ce200 rope: Micro optimize the creation of masks (#41132)
Using compiler explorer I saw that the compiler wasn't clever enough to
optimise away the branches in the masking code. I thought the compiler
would have a better chance if we always branched, which [turned out to
be the case](https://godbolt.org/z/PM594Pz18).

Running the benchmarks the biggest benefit I saw was:
```
push/65536              time:   [2.9067 ms 2.9243 ms 2.9417 ms]
                        thrpt:  [21.246 MiB/s 21.373 MiB/s 21.502 MiB/s]
                 change:
                        time:   [-8.3452% -7.2617% -6.2009%] (p = 0.00 < 0.05)
                        thrpt:  [+6.6108% +7.8303% +9.1050%]
                        Performance has improved.
```
But I did also see some regressions:
```
slice/4096              time:   [66.195 µs 66.815 µs 67.448 µs]
                        thrpt:  [57.915 MiB/s 58.464 MiB/s 59.012 MiB/s]
                 change:
                        time:   [+3.7131% +5.1698% +6.6971%] (p = 0.00 < 0.05)
                        thrpt:  [-6.2768% -4.9157% -3.5802%]
                        Performance has regressed.
```

Release Notes:

- N/A
2025-10-27 16:16:16 +01:00
Lukas Wirth
ae3abf50d8 editor: Fix panics in CursorPosition::update_position (#41237)
Fixes a regression introduced in
https://github.com/zed-industries/zed/pull/39857. As for the exact
reason this causes this issue I am not yet sure will investigate (as per
the todos in code)

Fixes ZED-23R

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-10-27 08:26:39 +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
Lukas Wirth
b519ab2758 rope: Improve chunk slicing panic messages (#41023)
We still see a bunch of panics here but the default slicing panic
doesn't tell which side of the range is bad

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-10-23 16:17:11 +00:00
Lukas Wirth
738e248109 gpui: Small perf optimizations (#40767)
Some random findings based on profiling

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-10-23 13:26:27 +00:00
Lukas Wirth
044701e3a5 rope: Implement Rope::is_char_boundary via chars bitmap (#40945)
Slightly more efficient. No new tests as we already have tests
verifiying this.

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-10-22 23:05:43 +00:00
Lukas Wirth
c81ffaffb6 editor: Use unbounded shifts for chunk bitmaps (#40879)
This simplifies some code and is also more correct in some others (I
believe some of these might've overflowed causing panics in sentry)

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-10-22 11:05:32 +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
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
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
Lukas Wirth
ec0eeaf69d rope: Assert utf8 boundary of start of Chunks::new range (#40253)
We seem to run into panics in related code, so better assert early

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-10-15 13:28:51 +00:00
Martin Pool
3d4d8ef6a8 Remove unnecessary clone from Rope::append (#39960)
The previous code clones all the rope chunks, but the rope is passed by
value so the chunks are about to be dropped anyhow.

I thought this may slightly help performance but it has no very
noticeable effect, with a mix of small changes up and down probably
attributable to noise on my machine?

I wonder if the benchmarks might just not hit this path well? I'm
looking into that separately (see #39949, #39951), but this seemed clear
enough to be worth proposing by itself.

Incidentally it surprised me this did not generate a warning already,
but I think it's because we're taking only one field from the struct
that's about to be dropped:
https://github.com/rust-lang/rust-clippy/issues/7429.

<details>

```

     Running benches/rope_benchmark.rs (target/release/deps/rope_benchmark-4c5c71666e7c1729)
push/4096               time:   [362.58 µs 366.40 µs 370.69 µs]
                        thrpt:  [10.538 MiB/s 10.661 MiB/s 10.773 MiB/s]
                 change:
                        time:   [+0.0646% +1.2362% +2.4681%] (p = 0.04 < 0.05)
                        thrpt:  [-2.4086% -1.2211% -0.0646%]
                        Change within noise threshold.
Found 10 outliers among 100 measurements (10.00%)
  7 (7.00%) high mild
  3 (3.00%) high severe
Benchmarking push/65536: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 8.4s, enable flat sampling, or reduce sample count to 50.
push/65536              time:   [1.6185 ms 1.6353 ms 1.6557 ms]
                        thrpt:  [37.747 MiB/s 38.219 MiB/s 38.616 MiB/s]
                 change:
                        time:   [+1.9135% +2.9548% +3.9838%] (p = 0.00 < 0.05)
                        thrpt:  [-3.8312% -2.8700% -1.8776%]
                        Performance has regressed.
Found 6 outliers among 100 measurements (6.00%)
  5 (5.00%) high mild
  1 (1.00%) high severe

append/4096             time:   [1.1052 µs 1.1104 µs 1.1162 µs]
                        thrpt:  [3.4177 GiB/s 3.4354 GiB/s 3.4516 GiB/s]
                 change:
                        time:   [-2.5075% -0.3430% +1.5095%] (p = 0.76 > 0.05)
                        thrpt:  [-1.4871% +0.3441% +2.5720%]
                        No change in performance detected.
Found 8 outliers among 100 measurements (8.00%)
  7 (7.00%) high mild
  1 (1.00%) high severe
append/65536            time:   [12.404 µs 12.444 µs 12.487 µs]
                        thrpt:  [4.8881 GiB/s 4.9049 GiB/s 4.9204 GiB/s]
                 change:
                        time:   [-0.1408% +0.5573% +1.2016%] (p = 0.10 > 0.05)
                        thrpt:  [-1.1874% -0.5542% +0.1410%]
                        No change in performance detected.
Found 5 outliers among 100 measurements (5.00%)
  2 (2.00%) high mild
  3 (3.00%) high severe

slice/4096              time:   [32.963 µs 33.185 µs 33.466 µs]
                        thrpt:  [116.72 MiB/s 117.71 MiB/s 118.51 MiB/s]
                 change:
                        time:   [-6.4303% -5.1234% -3.6394%] (p = 0.00 < 0.05)
                        thrpt:  [+3.7769% +5.4000% +6.8722%]
                        Performance has improved.
Found 2 outliers among 100 measurements (2.00%)
  1 (1.00%) high mild
  1 (1.00%) high severe
slice/65536             time:   [668.67 µs 670.49 µs 672.65 µs]
                        thrpt:  [92.916 MiB/s 93.215 MiB/s 93.469 MiB/s]
                 change:
                        time:   [+0.0846% +0.5573% +1.0199%] (p = 0.02 < 0.05)
                        thrpt:  [-1.0096% -0.5542% -0.0845%]
                        Change within noise threshold.
Found 10 outliers among 100 measurements (10.00%)
  6 (6.00%) high mild
  4 (4.00%) high severe

bytes_in_range/4096     time:   [5.1513 µs 5.1594 µs 5.1674 µs]
                        thrpt:  [755.95 MiB/s 757.12 MiB/s 758.31 MiB/s]
                 change:
                        time:   [-4.9410% -4.2051% -3.3835%] (p = 0.00 < 0.05)
                        thrpt:  [+3.5020% +4.3897% +5.1978%]
                        Performance has improved.
Found 4 outliers among 100 measurements (4.00%)
  1 (1.00%) low mild
  3 (3.00%) high severe
bytes_in_range/65536    time:   [139.87 µs 140.17 µs 140.55 µs]
                        thrpt:  [444.67 MiB/s 445.89 MiB/s 446.85 MiB/s]
                 change:
                        time:   [-0.6267% -0.0474% +0.4635%] (p = 0.87 > 0.05)
                        thrpt:  [-0.4614% +0.0475% +0.6306%]
                        No change in performance detected.
Found 9 outliers among 100 measurements (9.00%)
  7 (7.00%) high mild
  2 (2.00%) high severe

chars/4096              time:   [1.0243 µs 1.0250 µs 1.0257 µs]
                        thrpt:  [3.7190 GiB/s 3.7217 GiB/s 3.7243 GiB/s]
                 change:
                        time:   [+4.0106% +4.5396% +5.3062%] (p = 0.00 < 0.05)
                        thrpt:  [-5.0388% -4.3425% -3.8559%]
                        Performance has regressed.
Found 10 outliers among 100 measurements (10.00%)
  2 (2.00%) high mild
  8 (8.00%) high severe
chars/65536             time:   [17.540 µs 17.576 µs 17.614 µs]
                        thrpt:  [3.4652 GiB/s 3.4727 GiB/s 3.4797 GiB/s]
                 change:
                        time:   [+2.5201% +3.3922% +4.1639%] (p = 0.00 < 0.05)
                        thrpt:  [-3.9974% -3.2809% -2.4581%]
                        Performance has regressed.
Found 7 outliers among 100 measurements (7.00%)
  4 (4.00%) high mild
  3 (3.00%) high severe

clip_point/4096         time:   [58.857 µs 59.162 µs 59.490 µs]
                        thrpt:  [65.662 MiB/s 66.026 MiB/s 66.368 MiB/s]
                 change:
                        time:   [+1.6900% +2.8088% +3.8521%] (p = 0.00 < 0.05)
                        thrpt:  [-3.7092% -2.7321% -1.6619%]
                        Performance has regressed.
Found 3 outliers among 100 measurements (3.00%)
  3 (3.00%) high mild
clip_point/65536        time:   [1.8609 ms 1.8633 ms 1.8660 ms]
                        thrpt:  [33.494 MiB/s 33.543 MiB/s 33.585 MiB/s]
                 change:
                        time:   [+0.0577% +0.2579% +0.4495%] (p = 0.01 < 0.05)
                        thrpt:  [-0.4474% -0.2572% -0.0577%]
                        Change within noise threshold.
Found 5 outliers among 100 measurements (5.00%)
  3 (3.00%) high mild
  2 (2.00%) high severe

point_to_offset/4096    time:   [19.246 µs 19.287 µs 19.331 µs]
                        thrpt:  [202.07 MiB/s 202.54 MiB/s 202.97 MiB/s]
                 change:
                        time:   [+1.1073% +2.9754% +5.3818%] (p = 0.00 < 0.05)
                        thrpt:  [-5.1069% -2.8894% -1.0951%]
                        Performance has regressed.
Found 13 outliers among 100 measurements (13.00%)
  5 (5.00%) high mild
  8 (8.00%) high severe
Benchmarking point_to_offset/65536: Warming up for 3.0000 s
Warning: Unable to complete 100 samples in 5.0s. You may wish to increase target time to 6.6s, enable flat sampling, or reduce sample count to 60.
point_to_offset/65536   time:   [741.87 µs 743.28 µs 744.74 µs]
                        thrpt:  [83.922 MiB/s 84.086 MiB/s 84.247 MiB/s]
                 change:
                        time:   [+5.0577% +5.6751% +6.3133%] (p = 0.00 < 0.05)
                        thrpt:  [-5.9384% -5.3703% -4.8142%]
                        Performance has regressed.
Found 7 outliers among 100 measurements (7.00%)
  4 (4.00%) high mild
  3 (3.00%) high severe

cursor/4096             time:   [27.407 µs 27.483 µs 27.600 µs]
                        thrpt:  [141.53 MiB/s 142.13 MiB/s 142.53 MiB/s]
                 change:
                        time:   [-7.1479% -6.2928% -5.6378%] (p = 0.00 < 0.05)
                        thrpt:  [+5.9747% +6.7154% +7.6981%]
                        Performance has improved.
Found 9 outliers among 100 measurements (9.00%)
  1 (1.00%) high mild
  8 (8.00%) high severe
cursor/65536            time:   [848.91 µs 849.70 µs 850.59 µs]
                        thrpt:  [73.478 MiB/s 73.555 MiB/s 73.624 MiB/s]
                 change:
                        time:   [+0.0281% +0.3487% +0.6686%] (p = 0.04 < 0.05)
                        thrpt:  [-0.6642% -0.3475% -0.0281%]
                        Change within noise threshold.
Found 9 outliers among 100 measurements (9.00%)
  5 (5.00%) high mild
  4 (4.00%) high severe

```
</details>

Release Notes:

- N/A
2025-10-11 10:29:54 +03:00
Martin Pool
5b0a2f1ab6 Add more unit tests for Rope (#39426)
I was looking at the rope implementation and some of the existing bugs
that crash in there, and I ran cargo-mutants to inspect test coverage. I
was motivated by bugs like
https://github.com/zed-industries/zed/issues/38556 but this doesn't fix
it and the bug may well be at a higher layer.

This PR adds coverage for a few functions that aren't tested today. I
didn't find any actual bugs yet.

I can see this tree is pretty sparse on docstrings so if you think these
are too verbose I can take them out or drop the whole PR.

Release Notes:

- N/A
2025-10-05 21:42:27 +03: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
Lukas Wirth
a2c71d3d20 text: Assert text anchor offset validity on construction (#38441)
Attempt to aid debugging some utf8 indexing issues

Release Notes:

- N/A

Co-authored-by: Mikayla Maki <mikayla@zed.dev>
2025-09-22 11:20:46 +00:00
Anthony Eid
55d130a166 Fix chunks peek_with_bitmaps panic (#38430)
This panic only happened in debug builds because of a left shift
overflow. The slice range has bounds between 0 and 128. The 128 case
caused the overflow.

We now do an unbounded shift and a wrapped sub to get the correct
bitmask. If the slice range is 128 left, it should make 1 zero. Then the
wrapped sub would flip all bits, which is expected behavior.

Release Notes:

- N/A

Co-authored-by: Nia <nia@zed.dev>
2025-09-18 13:16:36 -04:00
Marshall Bowers
43f40c60fd rope: Fix spelling of peek_with_bitmaps (#38341)
This PR fixes the spelling of the `peek_with_bitmaps` method.

Release Notes:

- N/A
2025-09-17 17:02:13 +00:00
Anthony Eid
b8c30f448f Improve Tab Map performance (#32243)
## Context

While looking into: #32051 and #16120 with instruments, I noticed that
`TabSnapshot::to_tab_point` and `TabSnapshot::to_fold_point` are a
common bottleneck between the two issues. This PR takes the first steps
into closing the stated issues by improving the performance of both
those functions.

### Method

`to_tab_point` and `to_fold_point` iterate through each character in
their rows to find tab characters and translate those characters into
their respective transformations. This PR changes this iteration to take
advantage of the tab character bitmap in the `Rope` data structure and
goes directly to each tab character when iterating.

The tab bitmap is now passed from each layer in-between the `Rope` to
the `TabMap`.

### Testing 

I added several randomized tests to ensure that the new `to_tab_point`
and `to_fold_point` functions have the same behavior as the old methods
they're replacing. I also added `test_random_chunk_bitmap` on each layer
the tab bitmap is passed up to the `TabMap` to make sure that the bitmap
being passed is transformed correctly between the layers of
`DisplayMap`.

`test_random_chunk_bitmap` was added to these layers:
- buffer
- multi buffer
- custom_highlights
- inlay_map
- fold_map

## Benchmarking 

I setup benchmarks with criterion that is runnable via `cargo bench -p
editor --profile=release-fast`. When benchmarking I had my laptop
plugged in and did so from the terminal with a minimal amount of
processes running. I'm also on a m4 max

### Results 

#### To Tab Point

Went from completing 6.8M iterations in 5s with an average time of
`736.13 ns` to `683.38 ns` which is a `-7.1875%` improvement

#### To Fold Point

Went from completing 6.8M iterations in 5s with an average time of
`736.55 ns` to `682.40 ns` which is a `-7.1659%` improvement

#### Editor render 

Went from having an average render time of `62.561 µs` to `57.216 µs`
which is a `-8.8248%` improvement

#### Build Buffer with one long line

Went from having an average buffer build time of `3.2549 ms` to `3.2635
ms` which is a `+0.2151%` regression within the margin of error

#### Editor with 1000 multi cursor input 

Went from having an average edit time of `133.05 ms` to `122.96 ms`
which is a `-7.5776%` improvement

Release Notes:

- N/A

---------

Co-authored-by: Remco Smits <djsmits12@gmail.com>
Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
2025-09-10 16:13:41 -04:00
Michael Sloan
47a475681f Optimize Chunks::seek when offset is in current chunk (#37659)
Release Notes:

- N/A
2025-09-06 04:22:55 +00:00
Nathan Sobo
1ae326432e Extract a scheduler crate from GPUI to enable unified integration testing of client and server code (#37326)
Extracts and cleans up GPUI's scheduler code into a new `scheduler`
crate, making it pluggable by external runtimes. This will enable
deterministic integration testing with cloud components by providing a
unified test scheduler across Zed and backend code. In Zed, it will
replace the existing GPUI scheduler for consistent async task management
across platforms.

## Changes

- **Core Implementation**: `TestScheduler` with seed-based
randomization, session tracking (`SessionId`), and foreground/background
task separation for reproducible testing.
- **Executors**: `ForegroundExecutor` (!Send, thread-local) and
`BackgroundExecutor` (Send, with blocking/timeout support) as
GPUI-compatible wrappers.
- **Clock and Timer**: Controllable `TestClock` and future-based `Timer`
for time-sensitive tests.
- **Testing APIs**: `once()`, `with_seed()`, and `many()` methods for
configurable test runs.
- **Dependencies**: Added `async-task`, `chrono`, `futures`, etc., with
updates to `Cargo.toml` and lock file.

## Benefits

- **Integration Testing**: Facilitates reliable async tests involving
cloud sessions, reducing flakiness via deterministic execution.
- **Pluggability**: Trait-based design (`Scheduler`) allows easy
integration into non-GPUI runtimes while maintaining GPUI compatibility.
- **Cleanup**: Refactors GPUI scheduler logic for clarity, correctness
(no `unwrap()`, proper error handling), and extensibility.

Follows Rust guidelines; run `./script/clippy` for verification.

- [x] Define and test a core scheduler that we think can power our cloud
code and GPUI
- [ ] Replace GPUI's scheduler


Release Notes:

- N/A

---------

Co-authored-by: Antonio Scandurra <me@as-cii.com>
2025-09-04 17:14:53 +02:00
Michael Sloan
d7fd5910d7 Use slice from Rope chunk when possible while iterating lines (#37430)
Release Notes:

- N/A
2025-09-03 06:35:31 +00:00
tidely
7bdc99abc1 Fix clippy::redundant_clone lint violations (#36558)
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
2025-08-20 12:20:13 +02:00
Piotr Osiewicz
cf7c64d77f lints: A bunch of extra style lint fixes (#36568)
- **lints: Fix 'doc_lazy_continuation'**
- **lints: Fix 'doc_overindented_list_items'**
- **inherent_to_string and io_other_error**
- **Some more lint fixes**
- **lints: enable bool_assert_comparison, match_like_matches_macro and
wrong_self_convention**


Release Notes:

- N/A
2025-08-20 12:05:58 +02:00
Piotr Osiewicz
6825715503 Another batch of lint fixes (#36521)
- **Enable a bunch of extra lints**
- **First batch of fixes**
- **More fixes**

Release Notes:

- N/A
2025-08-19 20:33:44 +00:00
Piotr Osiewicz
05fc0c432c Fix a bunch of other low-hanging style lints (#36498)
- **Fix a bunch of low hanging style lints like unnecessary-return**
- **Fix single worktree violation**
- **And the rest**

Release Notes:

- N/A
2025-08-19 21:26:17 +02:00
Piotr Osiewicz
8f567383e4 Auto-fix clippy::collapsible_if violations (#36428)
Release Notes:

- N/A
2025-08-19 13:27:24 +00:00
Piotr Osiewicz
9e0e233319 Fix clippy::needless_borrow lint violations (#36444)
Release Notes:

- N/A
2025-08-18 21:54:35 +00:00
Lukas Wirth
4dbd24d75f Reduce amount of allocations in RustLsp label handling (#35786)
There can be a lot of completions after all


Release Notes:

- N/A
2025-08-07 13:24:29 +00:00
Piotr Osiewicz
07e3d53d58 sum_tree: Do not implement Dimension on tuples, use new Dimensions wrapper instead (#35482)
This is a bit of a readability improvement IMHO; I often find myself
confused when dealing when dimension pairs, as there's no easy way to
jump to the implementation of a dimension for tuples to remind myself
for the n-th time how exactly that impl works. Now it should be possible
to jump directly to that impl.

Another bonus is that Dimension supports 3-ary tuples as well - by using
a () as a default value of a 3rd dimension.


Release Notes:

- N/A
2025-08-05 00:37:22 +00:00
Piotr Osiewicz
64d0fec699 sum_tree: Store context on cursor (#34904)
This gets rid of the need to pass context to all cursor functions. In
practice context is always immutable when interacting with cursors.

A nicety of this is in the follow-up PR we will be able to implement
Iterator for all Cursors/filter cursors (hell, we may be able to get rid
of filter cursor altogether, as it is just a custom `filter` impl on
iterator trait).
Release Notes:

- N/A
2025-07-22 18:20:48 +02:00
Piotr Osiewicz
72bcb0beb7 chore: Fix warnings for Rust 1.89 (#32378)
Closes #ISSUE

Release Notes:

- N/A
2025-06-09 13:11:57 +02:00
Ben Kunkle
c0aa8f63fd zlog: Replace usages of env_logger in tests with zlog (#31436)
Also fixes:
https://github.com/zed-industries/zed/pull/31400#issuecomment-2908165249

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2025-05-26 11:48:50 -04:00
Piotr Osiewicz
c6e2d20a02 chore: Bump Rust version to 1.86 (#28021)
Closes #ISSUE

Release Notes:

- N/A
2025-04-03 23:32:50 +02:00
Piotr Osiewicz
dc64ec9cc8 chore: Bump Rust edition to 2024 (#27800)
Follow-up to https://github.com/zed-industries/zed/pull/27791

Release Notes:

- N/A
2025-03-31 20:55:27 +02:00
Piotr Osiewicz
0729d24d77 chore: Prepare for Rust edition bump to 2024 (without autofix) (#27791)
Successor to #27779 - in this PR I've applied changes manually, without
futzing with if let lifetimes at all.

Release Notes:

- N/A
2025-03-31 20:10:36 +02:00
Ben Kunkle
ff25fa24e7 Add support for auto-closing of JSX tags (#25681)
Closes #4271

Implemented by kicking of a task on the main thread at the end of
`Editor::handle_input` which waits for the buffer to be re-parsed before
checking if JSX tag completion possible based on the recent edits, and
if it is then it spawns a task on the background thread to generate the
edits to be auto-applied to the buffer

Release Notes:

- Added support for auto-closing of JSX tags

---------

Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: Max Brunsfeld <max@zed.dev>
Co-authored-by: Marshall Bowers <git@maxdeviant.com>
Co-authored-by: Mikayla <mikayla@zed.dev>
Co-authored-by: Peter Tripp <peter@zed.dev>
2025-03-06 08:36:10 -06:00
Piotr Osiewicz
e4e758db3a Rust 1.85 (#25272)
Closes #ISSUE

Release Notes:

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

---------

Co-authored-by: Anthony Eid <hello@anthonyeid.me>
2025-02-28 18:33:35 +01:00
João Marcos
a8de6af641 Fix editor::SplitSelectionIntoLines adding an extra line at the end (#25053)
Closes #4795

Release Notes:

- Fixed `editor::SplitSelectionIntoLines` adding an extra line at end
of selection
2025-02-18 03:23:48 +00:00
Cole Miller
5704b50fb1 git: Compute and synchronize diffs from HEAD (#23626)
This PR builds on #21258 to make it possible to use HEAD as a diff base.
The buffer store is extended to support holding multiple change sets,
and collab gains support for synchronizing the committed text of files
when any collaborator requires it.

Not implemented in this PR:

- Exposing the diff from HEAD to the user
- Decorating the diff from HEAD with information about which hunks are
staged

`test_random_multibuffer` now fails first at `SEED=13277`, similar to
the previous high-water mark, but with various bugs in the multibuffer
logic now shaken out.

Release Notes:

- N/A

---------

Co-authored-by: Max <max@zed.dev>
Co-authored-by: Ben <ben@zed.dev>
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Co-authored-by: Conrad <conrad@zed.dev>
2025-02-04 15:29:10 -05:00
Conrad Irwin
45708d2680 Project Diff 2 (#23891)
This adds a new version of the project diff editor to go alongside the
new git panel.

The basics seem to be working, but still todo:

* [ ] Fix untracked files
* [ ] Fix deleted files
* [ ] Show commit message editor at top
* [x] Handle empty state
* [x] Fix panic where locator sometimes seeks to wrong excerpt

Release Notes:

- N/A
2025-02-03 13:18:50 -07:00
Kirill Bulatov
da2bd4b8e9 Rework go to line infrastructure (#23654)
Closes https://github.com/zed-industries/zed/issues/12024


https://github.com/user-attachments/assets/60ea3dbd-b594-4bf5-a44d-4bff925b815f

* Fixes incorrect line selection for certain corner cases

Before:

<img width="1728" alt="image"
src="https://github.com/user-attachments/assets/35aaee6c-c120-4bf1-9355-448a29d1b9b5"
/>

After:

<img width="1728" alt="image"
src="https://github.com/user-attachments/assets/abd97339-4594-4e8e-8605-50d74581ae86"
/>


* Reworks https://github.com/zed-industries/zed/pull/16420 to display
selection length with less performance overhead.
Improves the performance more, doing a single selections loop instead of
two.

* Fixes incorrect caret position display when text contains UTF-8 chars
with size > 1
Also fixes tooltop values for this case

* Fixes go to line to treat UTF-8 chars with size > 1 properly when
navigating

* Adds a way to fill go to line text editor with its tooltip on `Tab`

Release Notes:

- Fixed incorrect UTF-8 characters handling in `GoToLine` and caret
position
2025-01-25 19:24:19 +00:00
Max Brunsfeld
d2c55cbe3d Rework diff rendering to allow putting the cursor into deleted text, soft-wrapping and scrolling deleted text correctly (#22994)
Closes #12553

* [x] Fix `diff_hunk_before`
* [x] Fix failure to show deleted text when expanding hunk w/ cursor on
second line of the hunk
* [x] Failure to expand diff hunk below the cursor.
* [x] Delete the whole file, and expand the diff. Backspace over the
deleted hunk, panic!
* [x] Go-to-line now counts the diff hunks, but it should not
* [x] backspace at the beginning of a deleted hunk deletes too much text
* [x] Indent guides are rendered incorrectly 
* [ ] Fix randomized multi buffer tests

Maybe:
* [ ] Buffer search should include deleted text (in vim mode it turns
out I use `/x` all the time to jump to the next x I can see).
* [ ] vim: should refuse to switch into insert mode if selection is
fully within a diff.
* [ ] vim `o` command when cursor is on last line of deleted hunk.
* [ ] vim `shift-o` on first line of deleted hunk moves cursor but
doesn't insert line
* [x] `enter` at end of diff hunk inserts a new line but doesn't move
cursor
* [x] (`shift-enter` at start of diff hunk does nothing)
* [ ] Inserting a line just before an expanded hunk collapses it

Release Notes:


- Improved diff rendering, allowing you to navigate with your cursor
inside of deleted text in diff hunks.

---------

Co-authored-by: Conrad <conrad@zed.dev>
Co-authored-by: Cole <cole@zed.dev>
Co-authored-by: Mikayla <mikayla@zed.dev>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Co-authored-by: Michael <michael@zed.dev>
Co-authored-by: Agus <agus@zed.dev>
Co-authored-by: João <joao@zed.dev>
2025-01-24 14:18:22 -07:00