Add a prototype with a multi buffer having all project git changes (#21543)
Part of https://github.com/zed-industries/zed/issues/20925 This prototype is behind a feature flag and being merged to avoid conflicts with further git-related resturctures. To be a proper, public feature, this needs at least: * showing deleted files * better performance * randomized tests * `TODO`s in the `project_diff.rs` file fixed The good thing is, >90% of the changes are in the `project_diff.rs` file only, have a basic test and already work on simple cases. Release Notes: - N/A --------- Co-authored-by: Thorsten Ball <thorsten@zed.dev> Co-authored-by: Cole Miller <cole@zed.dev>
This commit is contained in:
parent
f0fac41ca4
commit
8d18dfa4c1
13 changed files with 1269 additions and 27 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -3790,6 +3790,7 @@ dependencies = [
|
|||
"db",
|
||||
"emojis",
|
||||
"env_logger 0.11.5",
|
||||
"feature_flags",
|
||||
"file_icons",
|
||||
"fs",
|
||||
"futures 0.3.31",
|
||||
|
@ -3823,6 +3824,7 @@ dependencies = [
|
|||
"snippet",
|
||||
"sum_tree",
|
||||
"task",
|
||||
"tempfile",
|
||||
"text",
|
||||
"theme",
|
||||
"time",
|
||||
|
|
|
@ -39,6 +39,7 @@ collections.workspace = true
|
|||
convert_case.workspace = true
|
||||
db.workspace = true
|
||||
emojis.workspace = true
|
||||
feature_flags.workspace = true
|
||||
file_icons.workspace = true
|
||||
futures.workspace = true
|
||||
fuzzy.workspace = true
|
||||
|
@ -97,6 +98,7 @@ project = { workspace = true, features = ["test-support"] }
|
|||
release_channel.workspace = true
|
||||
rand.workspace = true
|
||||
settings = { workspace = true, features = ["test-support"] }
|
||||
tempfile.workspace = true
|
||||
text = { workspace = true, features = ["test-support"] }
|
||||
theme = { workspace = true, features = ["test-support"] }
|
||||
tree-sitter-html.workspace = true
|
||||
|
|
|
@ -327,6 +327,7 @@ pub fn init(cx: &mut AppContext) {
|
|||
.detach();
|
||||
}
|
||||
});
|
||||
git::project_diff::init(cx);
|
||||
}
|
||||
|
||||
pub struct SearchWithinRange;
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
pub mod blame;
|
||||
pub mod project_diff;
|
||||
|
|
|
@ -154,7 +154,7 @@ impl GitBlame {
|
|||
this.generate(cx);
|
||||
}
|
||||
}
|
||||
project::Event::WorktreeUpdatedGitRepositories => {
|
||||
project::Event::WorktreeUpdatedGitRepositories(_) => {
|
||||
log::debug!("Status of git repositories updated. Regenerating blame data...",);
|
||||
this.generate(cx);
|
||||
}
|
||||
|
|
1235
crates/editor/src/git/project_diff.rs
Normal file
1235
crates/editor/src/git/project_diff.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -648,7 +648,7 @@ impl FileFinderDelegate {
|
|||
cx.subscribe(project, |file_finder, _, event, cx| {
|
||||
match event {
|
||||
project::Event::WorktreeUpdatedEntries(_, _)
|
||||
| project::Event::WorktreeAdded
|
||||
| project::Event::WorktreeAdded(_)
|
||||
| project::Event::WorktreeRemoved(_) => file_finder
|
||||
.picker
|
||||
.update(cx, |picker, cx| picker.refresh(cx)),
|
||||
|
|
|
@ -80,7 +80,6 @@ impl BufferDiff {
|
|||
self.tree.is_empty()
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn hunks_in_row_range<'a>(
|
||||
&'a self,
|
||||
range: Range<u32>,
|
||||
|
|
|
@ -3998,7 +3998,6 @@ impl BufferSnapshot {
|
|||
}
|
||||
|
||||
/// Returns all the Git diff hunks intersecting the given row range.
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn git_diff_hunks_in_row_range(
|
||||
&self,
|
||||
range: Range<BufferRow>,
|
||||
|
|
|
@ -240,11 +240,11 @@ pub enum Event {
|
|||
LanguageNotFound(Model<Buffer>),
|
||||
ActiveEntryChanged(Option<ProjectEntryId>),
|
||||
ActivateProjectPanel,
|
||||
WorktreeAdded,
|
||||
WorktreeAdded(WorktreeId),
|
||||
WorktreeOrderChanged,
|
||||
WorktreeRemoved(WorktreeId),
|
||||
WorktreeUpdatedEntries(WorktreeId, UpdatedEntriesSet),
|
||||
WorktreeUpdatedGitRepositories,
|
||||
WorktreeUpdatedGitRepositories(WorktreeId),
|
||||
DiskBasedDiagnosticsStarted {
|
||||
language_server_id: LanguageServerId,
|
||||
},
|
||||
|
@ -259,7 +259,7 @@ pub enum Event {
|
|||
DisconnectedFromHost,
|
||||
DisconnectedFromSshRemote,
|
||||
Closed,
|
||||
DeletedEntry(ProjectEntryId),
|
||||
DeletedEntry(WorktreeId, ProjectEntryId),
|
||||
CollaboratorUpdated {
|
||||
old_peer_id: proto::PeerId,
|
||||
new_peer_id: proto::PeerId,
|
||||
|
@ -1504,6 +1504,7 @@ impl Project {
|
|||
cx: &mut ModelContext<Self>,
|
||||
) -> Option<Task<Result<()>>> {
|
||||
let worktree = self.worktree_for_entry(entry_id, cx)?;
|
||||
cx.emit(Event::DeletedEntry(worktree.read(cx).id(), entry_id));
|
||||
worktree.update(cx, |worktree, cx| {
|
||||
worktree.delete_entry(entry_id, trash, cx)
|
||||
})
|
||||
|
@ -2204,7 +2205,7 @@ impl Project {
|
|||
match event {
|
||||
WorktreeStoreEvent::WorktreeAdded(worktree) => {
|
||||
self.on_worktree_added(worktree, cx);
|
||||
cx.emit(Event::WorktreeAdded);
|
||||
cx.emit(Event::WorktreeAdded(worktree.read(cx).id()));
|
||||
}
|
||||
WorktreeStoreEvent::WorktreeRemoved(_, id) => {
|
||||
cx.emit(Event::WorktreeRemoved(*id));
|
||||
|
@ -2225,23 +2226,25 @@ impl Project {
|
|||
}
|
||||
}
|
||||
cx.observe(worktree, |_, _, cx| cx.notify()).detach();
|
||||
cx.subscribe(worktree, |project, worktree, event, cx| match event {
|
||||
worktree::Event::UpdatedEntries(changes) => {
|
||||
cx.emit(Event::WorktreeUpdatedEntries(
|
||||
worktree.read(cx).id(),
|
||||
changes.clone(),
|
||||
));
|
||||
cx.subscribe(worktree, |project, worktree, event, cx| {
|
||||
let worktree_id = worktree.update(cx, |worktree, _| worktree.id());
|
||||
match event {
|
||||
worktree::Event::UpdatedEntries(changes) => {
|
||||
cx.emit(Event::WorktreeUpdatedEntries(
|
||||
worktree.read(cx).id(),
|
||||
changes.clone(),
|
||||
));
|
||||
|
||||
let worktree_id = worktree.update(cx, |worktree, _| worktree.id());
|
||||
project
|
||||
.client()
|
||||
.telemetry()
|
||||
.report_discovered_project_events(worktree_id, changes);
|
||||
project
|
||||
.client()
|
||||
.telemetry()
|
||||
.report_discovered_project_events(worktree_id, changes);
|
||||
}
|
||||
worktree::Event::UpdatedGitRepositories(_) => {
|
||||
cx.emit(Event::WorktreeUpdatedGitRepositories(worktree_id));
|
||||
}
|
||||
worktree::Event::DeletedEntry(id) => cx.emit(Event::DeletedEntry(worktree_id, *id)),
|
||||
}
|
||||
worktree::Event::UpdatedGitRepositories(_) => {
|
||||
cx.emit(Event::WorktreeUpdatedGitRepositories);
|
||||
}
|
||||
worktree::Event::DeletedEntry(id) => cx.emit(Event::DeletedEntry(*id)),
|
||||
})
|
||||
.detach();
|
||||
cx.notify();
|
||||
|
|
|
@ -304,7 +304,7 @@ impl ProjectPanel {
|
|||
cx.notify();
|
||||
}
|
||||
project::Event::WorktreeUpdatedEntries(_, _)
|
||||
| project::Event::WorktreeAdded
|
||||
| project::Event::WorktreeAdded(_)
|
||||
| project::Event::WorktreeOrderChanged => {
|
||||
this.update_visible_entries(None, cx);
|
||||
cx.notify();
|
||||
|
|
|
@ -125,7 +125,7 @@ impl ProjectIndex {
|
|||
cx: &mut ModelContext<Self>,
|
||||
) {
|
||||
match event {
|
||||
project::Event::WorktreeAdded | project::Event::WorktreeRemoved(_) => {
|
||||
project::Event::WorktreeAdded(_) | project::Event::WorktreeRemoved(_) => {
|
||||
self.update_worktree_indices(cx);
|
||||
}
|
||||
_ => {}
|
||||
|
|
|
@ -810,7 +810,7 @@ impl Workspace {
|
|||
this.collaborator_left(*peer_id, cx);
|
||||
}
|
||||
|
||||
project::Event::WorktreeRemoved(_) | project::Event::WorktreeAdded => {
|
||||
project::Event::WorktreeRemoved(_) | project::Event::WorktreeAdded(_) => {
|
||||
this.update_window_title(cx);
|
||||
this.serialize_workspace(cx);
|
||||
}
|
||||
|
@ -832,7 +832,7 @@ impl Workspace {
|
|||
cx.remove_window();
|
||||
}
|
||||
|
||||
project::Event::DeletedEntry(entry_id) => {
|
||||
project::Event::DeletedEntry(_, entry_id) => {
|
||||
for pane in this.panes.iter() {
|
||||
pane.update(cx, |pane, cx| {
|
||||
pane.handle_deleted_project_item(*entry_id, cx)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue