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
Release Notes:
- Fixed a rendering bug that caused context in the agent to not wrap
properly.
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Co-authored-by: Zed AI <ai+claude-3.7@zed.dev>
There's still a bit more work to do on this, but this PR is compiling
(with warnings) after eliminating the key types. When the tasks below
are complete, this will be the new narrative for GPUI:
- `Entity<T>` - This replaces `View<T>`/`Model<T>`. It represents a unit
of state, and if `T` implements `Render`, then `Entity<T>` implements
`Element`.
- `&mut App` This replaces `AppContext` and represents the app.
- `&mut Context<T>` This replaces `ModelContext` and derefs to `App`. It
is provided by the framework when updating an entity.
- `&mut Window` Broken out of `&mut WindowContext` which no longer
exists. Every method that once took `&mut WindowContext` now takes `&mut
Window, &mut App` and every method that took `&mut ViewContext<T>` now
takes `&mut Window, &mut Context<T>`
Not pictured here are the two other failed attempts. It's been quite a
month!
Tasks:
- [x] Remove `View`, `ViewContext`, `WindowContext` and thread through
`Window`
- [x] [@cole-miller @mikayla-maki] Redraw window when entities change
- [x] [@cole-miller @mikayla-maki] Get examples and Zed running
- [x] [@cole-miller @mikayla-maki] Fix Zed rendering
- [x] [@mikayla-maki] Fix todo! macros and comments
- [x] Fix a bug where the editor would not be redrawn because of view
caching
- [x] remove publicness window.notify() and replace with
`AppContext::notify`
- [x] remove `observe_new_window_models`, replace with
`observe_new_models` with an optional window
- [x] Fix a bug where the project panel would not be redrawn because of
the wrong refresh() call being used
- [x] Fix the tests
- [x] Fix warnings by eliminating `Window` params or using `_`
- [x] Fix conflicts
- [x] Simplify generic code where possible
- [x] Rename types
- [ ] Update docs
### issues post merge
- [x] Issues switching between normal and insert mode
- [x] Assistant re-rendering failure
- [x] Vim test failures
- [x] Mac build issue
Release Notes:
- N/A
---------
Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: Mikayla <mikayla@zed.dev>
Co-authored-by: Joseph <joseph@zed.dev>
Co-authored-by: max <max@zed.dev>
Co-authored-by: Michael Sloan <michael@zed.dev>
Co-authored-by: Mikayla Maki <mikaylamaki@Mikaylas-MacBook-Pro.local>
Co-authored-by: Mikayla <mikayla.c.maki@gmail.com>
Co-authored-by: joão <joao@zed.dev>
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>
In #14567 I claimed that the underlying allocation is reused. And it
was. At the time I've submitted a PR I was using `.filter_map(|x| x)`,
which got flagged by clippy as something that could be simplified to
`.flatten()` - that however broke the allocation reuse promise.
Thus, this PR goes back to using `filter_map` and additionally in debug
builds it performs checks for allocation reuse. With .flatten in place,
a bunch of unit test fail on that branch, so the checks do work.
Release Notes:
- N/A
# Background
In https://github.com/zed-industries/zed/issues/14408 we received a
repro for "Replace all" being slow, even after the work I did
https://github.com/zed-industries/zed/pull/13654. Admittedly #13654 was
a pretty straightforward change.
Under the profiler it turned out that we're spending *10 seconds* in
`memmove` on main thread. Ugh. Not great. The direct ancestor of the
memmove call was
66f0c390a8/crates/editor/src/display_map/tab_map.rs (L108-L119)
What?
# Accidental O(n^2)
We have a bunch of `consolidate_*_edits` functions which take a list of
Fold/Tab/Inlay/Wrap edits and merge consecutive edits if their ranges
overlap/are next to one another. The loop usually goes as follows:
```
while ix < edits.len() {
let (prev_edits, next_edits) = edits.split_at_mut(ix);
let prev_edit = prev_edits.last_mut().unwrap();
let edit = &next_edits[0];
if PREV_EDIT_CAN_BE_MERGED_WITH_CURRENT_ONE {
MERGE_EDITS(prev_edit, edit);
edits.remove(ix); // !!
} else {
ix += 1;
}
}
```
The problem is the call to `.remove` - it has to shift all of the
consecutive elements in the `edits` vector! Thus, when processing the
edits from the original repro (where consolidation shrinks the edit list
from 210k entries to 30k), we mostly spend time moving entries in memory
around.
Thus, the original repro isn't really an issue with replace_all; it's
just that replace_all is one of the few tools available to the end user
that can apply large # of edits in a single transaction.
# Solution
In this PR I address the issue by rewriting the loop in a way that does
not throw items away via `.remove`. Instead, `Iterator::scan` is used,
which lets us achieve the same logic without having the pitfalls of
`.remove`s.
Crucially, **this code does not allocate a new backing buffer for
edits** (see [this article for
rationale](https://blog.polybdenum.com/2024/01/17/identifying-the-collect-vec-memory-leak-footgun.html));
with `vec.into_iter().scan().filter_map().collect()` we still use the
same underlying buffer as the one that's passed into `consolidate_*`
functions. In development I verified that by checking whether the
pointers to backing storage of a Vec are the same before and after the
consolidation.
# Results
### Before
Nightly 0.145.0
[66f0c390a8](66f0c390a8)
https://github.com/user-attachments/assets/8b0ad3bc-86d6-4f8a-850c-ebb86e8b3bfc
(~13s end-to-end)
### After
https://github.com/user-attachments/assets/366835db-1d84-4f95-8c74-b1506a9fabec
(~2s end-to-end)
The remaining lag is (I think) lies in `TextSummary` calculation and not
the consolidation itself. Thus, for the purposes of scoping this PR,
I'll tackle it separately.
Release Notes:
- Significantly improved performance of applying large quantities of
concurrent edits (e.g. when running "Replace all").
This pull request replaces the static `⋯` character we used to insert
when folding a range with a custom render function that return an
`AnyElement`. We plan to use this in the assistant, but for now this
should be behavior-preserving.
Release Notes:
- N/A
---------
Co-authored-by: Nathan <nathan@zed.dev>
Co-authored-by: Conrad <conrad@zed.dev>
- Moves languages module from `zed` into a separate crate. That way we
have less of a long pole at the end of compilation.
- Removes moot dependencies on editor/picker. This is totally harmless
and might help in the future if we decide to decouple picker from
editor.
Before:
```
Number of crates that depend on 'picker' but not on 'editor': 1
Total number of crates that depend on 'picker': 13
Total number of crates that depend on 'editor': 30
```
After:
```
Number of crates that depend on 'picker' but not on 'editor': 5
Total number of crates that depend on 'picker': 12
Total number of crates that depend on 'editor': 26
```
The more crates depend on just picker but not editor, the better in that
case.
Release Notes:
- N/A
Hopefully this makes it a bit easier for new contributors to dive into
the codebase :)
Release Notes:
- Improved documentation for many core editor types
---------
Co-authored-by: Nathan Sobo <nathan@zed.dev>
Instead of looking for `\n` as a stopping condition, we cap the range
we pass to `SuggestionSnapshot::chunks` to stop on the next line. This
makes character searching faster, because looking for a single character
uses `memchr`. Also, this avoids an extra conditional in a tight loop such
as the chunk scanning one contained in `TabMap::sync`.