From a63eca8f65050641733be7828f747aace1e36087 Mon Sep 17 00:00:00 2001 From: Cole Miller Date: Mon, 8 Dec 2025 20:09:04 -0500 Subject: [PATCH] push bufferdiff refactor through most of the workspace Co-authored-by: cameron --- crates/acp_thread/src/diff.rs | 109 ++++++++---------- crates/action_log/src/action_log.rs | 53 ++++----- crates/agent_ui/src/agent_diff.rs | 6 +- crates/buffer_diff/src/buffer_diff.rs | 64 +++++----- crates/editor/src/editor.rs | 2 +- crates/editor/src/editor_tests.rs | 16 ++- crates/editor/src/split.rs | 4 +- crates/eval/src/example.rs | 7 +- crates/git_ui/src/commit_view.rs | 39 +++---- crates/git_ui/src/file_diff_view.rs | 55 +++++---- crates/git_ui/src/project_diff.rs | 4 +- crates/git_ui/src/text_diff_view.rs | 16 +-- crates/language/src/buffer.rs | 2 +- crates/multi_buffer/src/multi_buffer.rs | 25 ++-- crates/project/src/git_store.rs | 5 +- crates/project/src/project_tests.rs | 86 ++++++++------ .../remote_server/src/remote_editing_tests.rs | 35 +++--- crates/rope/src/chunk.rs | 1 - crates/zeta/src/rate_prediction_modal.rs | 15 +-- 19 files changed, 277 insertions(+), 267 deletions(-) diff --git a/crates/acp_thread/src/diff.rs b/crates/acp_thread/src/diff.rs index aa2e3e7f514704037f56c37acc47e0739b3fd87f..c657e25eab8b8cf1495bbb7b8b80e405128c6b9f 100644 --- a/crates/acp_thread/src/diff.rs +++ b/crates/acp_thread/src/diff.rs @@ -1,10 +1,10 @@ use anyhow::Result; -use buffer_diff::{BufferDiff, BufferDiffSnapshot}; +use buffer_diff::BufferDiff; use editor::{MultiBuffer, PathKey, multibuffer_context_lines}; use gpui::{App, AppContext, AsyncApp, Context, Entity, Subscription, Task}; use itertools::Itertools; use language::{ - Anchor, Buffer, Capability, LanguageRegistry, OffsetRangeExt as _, Point, Rope, TextBuffer, + Anchor, Buffer, Capability, LanguageRegistry, OffsetRangeExt as _, Point, TextBuffer, }; use std::{cmp::Reverse, ops::Range, path::Path, sync::Arc}; use util::ResultExt; @@ -49,15 +49,15 @@ impl Diff { .update(cx, |multibuffer, cx| { let hunk_ranges = { let buffer = buffer.read(cx); - let diff = diff.read(cx); - diff.hunks_intersecting_range( - Anchor::min_for_buffer(buffer.remote_id()) - ..Anchor::max_for_buffer(buffer.remote_id()), - buffer, - cx, - ) - .map(|diff_hunk| diff_hunk.buffer_range.to_point(buffer)) - .collect::>() + diff.read(cx) + .snapshot(cx) + .hunks_intersecting_range( + Anchor::min_for_buffer(buffer.remote_id()) + ..Anchor::max_for_buffer(buffer.remote_id()), + buffer, + ) + .map(|diff_hunk| diff_hunk.buffer_range.to_point(buffer)) + .collect::>() }; multibuffer.set_excerpts_for_path( @@ -168,7 +168,7 @@ impl Diff { new_buffer, .. }) => { - base_text.as_str() != old_text + base_text.as_ref() != old_text || !new_buffer.read(cx).as_rope().chunks().equals_str(new_text) } Diff::Finalized(FinalizedDiff { @@ -176,7 +176,7 @@ impl Diff { new_buffer, .. }) => { - base_text.as_str() != old_text + base_text.as_ref() != old_text || !new_buffer.read(cx).as_rope().chunks().equals_str(new_text) } } @@ -200,21 +200,22 @@ impl PendingDiff { let base_text = self.base_text.clone(); self.update_diff = cx.spawn(async move |diff, cx| { let text_snapshot = buffer.read_with(cx, |buffer, _| buffer.text_snapshot())?; - let diff_snapshot = BufferDiff::update_diff( - buffer_diff.clone(), - text_snapshot.clone(), - Some(base_text), - false, - false, - None, - None, - cx, - ) - .await?; + let language = buffer.read_with(cx, |buffer, _| buffer.language().cloned())?; + let update = buffer_diff + .update(cx, |diff, cx| { + diff.update_diff( + text_snapshot.clone(), + Some(base_text.clone()), + false, + language, + cx, + ) + })? + .await; buffer_diff.update(cx, |diff, cx| { - diff.set_snapshot(diff_snapshot.clone(), &text_snapshot, cx); + diff.set_snapshot(update.clone(), &text_snapshot, false, cx); diff.secondary_diff().unwrap().update(cx, |diff, cx| { - diff.set_snapshot(diff_snapshot.clone(), &text_snapshot, cx); + diff.set_snapshot(update, &text_snapshot, false, cx); }); })?; diff.update(cx, |diff, cx| { @@ -311,13 +312,14 @@ impl PendingDiff { fn excerpt_ranges(&self, cx: &App) -> Vec> { let buffer = self.new_buffer.read(cx); - let diff = self.diff.read(cx); - let mut ranges = diff + let mut ranges = self + .diff + .read(cx) + .snapshot(cx) .hunks_intersecting_range( Anchor::min_for_buffer(buffer.remote_id()) ..Anchor::max_for_buffer(buffer.remote_id()), buffer, - cx, ) .map(|diff_hunk| diff_hunk.buffer_range.to_point(buffer)) .collect::>(); @@ -349,60 +351,47 @@ impl PendingDiff { pub struct FinalizedDiff { path: String, - base_text: Arc, + base_text: Arc, new_buffer: Entity, multibuffer: Entity, _update_diff: Task>, } async fn build_buffer_diff( - old_text: Arc, + old_text: Arc, buffer: &Entity, language_registry: Option>, cx: &mut AsyncApp, ) -> Result> { + let language = cx.update(|cx| buffer.read(cx).language().cloned())?; let buffer = cx.update(|cx| buffer.read(cx).snapshot())?; - let old_text_rope = cx - .background_spawn({ - let old_text = old_text.clone(); - async move { Rope::from(old_text.as_str()) } - }) - .await; - let base_buffer = cx - .update(|cx| { - Buffer::build_snapshot( - old_text_rope, - buffer.language().cloned(), - language_registry, - cx, - ) - })? - .await; + let secondary_diff = cx.new(|cx| BufferDiff::new(&buffer, cx))?; - let diff_snapshot = cx - .update(|cx| { - BufferDiffSnapshot::new_with_base_buffer( + let update = secondary_diff + .update(cx, |secondary_diff, cx| { + secondary_diff.update_diff( buffer.text.clone(), Some(old_text), - base_buffer, + true, + language.clone(), cx, ) })? .await; - let secondary_diff = cx.new(|cx| { - let mut diff = BufferDiff::new(&buffer, cx); - diff.set_snapshot(diff_snapshot.clone(), &buffer, cx); - diff + secondary_diff.update(cx, |secondary_diff, cx| { + secondary_diff.language_changed(language.clone(), language_registry.clone(), cx); + secondary_diff.set_snapshot(update.clone(), &buffer, true, cx); })?; - cx.new(|cx| { - let mut diff = BufferDiff::new(&buffer.text, cx); - diff.set_snapshot(diff_snapshot, &buffer, cx); + let diff = cx.new(|cx| BufferDiff::new(&buffer, cx))?; + diff.update(cx, |diff, cx| { + diff.language_changed(language, language_registry, cx); + diff.set_snapshot(update.clone(), &buffer, true, cx); diff.set_secondary_diff(secondary_diff); - diff - }) + })?; + Ok(diff) } #[cfg(test)] diff --git a/crates/action_log/src/action_log.rs b/crates/action_log/src/action_log.rs index 80c9438bc9f8051cb58357e56a82b5307fd20b75..529c87b49b3291e0649aaa03e50449052417d413 100644 --- a/crates/action_log/src/action_log.rs +++ b/crates/action_log/src/action_log.rs @@ -262,7 +262,7 @@ impl ActionLog { ); } - (Arc::new(base_text.to_string()), base_text) + (Arc::from(base_text.to_string().as_str()), base_text) } }); @@ -302,7 +302,7 @@ impl ActionLog { .context("buffer not tracked")?; let old_unreviewed_edits = tracked_buffer.unreviewed_edits.clone(); let agent_diff_base = tracked_buffer.diff_base.clone(); - let git_diff_base = git_diff.read(cx).base_text().as_rope().clone(); + let git_diff_base = git_diff.read(cx).base_text(cx).as_rope().clone(); let buffer_text = tracked_buffer.snapshot.as_rope().clone(); anyhow::Ok(cx.background_spawn(async move { let mut old_unreviewed_edits = old_unreviewed_edits.into_iter().peekable(); @@ -352,7 +352,7 @@ impl ActionLog { } ( - Arc::new(new_agent_diff_base.to_string()), + Arc::from(new_agent_diff_base.to_string().as_str()), new_agent_diff_base, ) })) @@ -374,11 +374,11 @@ impl ActionLog { this: &WeakEntity, buffer: &Entity, buffer_snapshot: text::BufferSnapshot, - new_base_text: Arc, + new_base_text: Arc, new_diff_base: Rope, cx: &mut AsyncApp, ) -> Result<()> { - let (diff, language, language_registry) = this.read_with(cx, |this, cx| { + let (diff, language) = this.read_with(cx, |this, cx| { let tracked_buffer = this .tracked_buffers .get(buffer) @@ -386,25 +386,28 @@ impl ActionLog { anyhow::Ok(( tracked_buffer.diff.clone(), buffer.read(cx).language().cloned(), - buffer.read(cx).language_registry(), )) })??; - let diff_snapshot = BufferDiff::update_diff( - diff.clone(), - buffer_snapshot.clone(), - Some(new_base_text), - true, - false, - language, - language_registry, - cx, - ) - .await; + let update = diff.update(cx, |diff, cx| { + diff.update_diff( + buffer_snapshot.clone(), + Some(new_base_text), + true, + language, + cx, + ) + }); let mut unreviewed_edits = Patch::default(); - if let Ok(diff_snapshot) = diff_snapshot { + if let Ok(update) = update { + let update = update.await; + + let diff_snapshot = diff.update(cx, |diff, cx| { + diff.set_snapshot(update.clone(), &buffer_snapshot, true, cx); + diff.snapshot(cx) + })?; + unreviewed_edits = cx .background_spawn({ - let diff_snapshot = diff_snapshot.clone(); let buffer_snapshot = buffer_snapshot.clone(); let new_diff_base = new_diff_base.clone(); async move { @@ -431,10 +434,6 @@ impl ActionLog { } }) .await; - - diff.update(cx, |diff, cx| { - diff.set_snapshot(diff_snapshot, &buffer_snapshot, cx); - })?; } this.update(cx, |this, cx| { let tracked_buffer = this @@ -975,7 +974,8 @@ impl TrackedBuffer { fn has_edits(&self, cx: &App) -> bool { self.diff .read(cx) - .hunks(self.buffer.read(cx), cx) + .snapshot(cx) + .hunks(self.buffer.read(cx)) .next() .is_some() } @@ -2388,13 +2388,14 @@ mod tests { ( buffer, diff.read(cx) - .hunks(&snapshot, cx) + .snapshot(cx) + .hunks(&snapshot) .map(|hunk| HunkStatus { diff_status: hunk.status().kind, range: hunk.range, old_text: diff .read(cx) - .base_text() + .base_text(cx) .text_for_range(hunk.diff_base_byte_range) .collect(), }) diff --git a/crates/agent_ui/src/agent_diff.rs b/crates/agent_ui/src/agent_diff.rs index 11acd649ef9df500edf99926e754228e4c41e7bc..8ddd77b9edd4e575e75686751bdb1146e4cf98f8 100644 --- a/crates/agent_ui/src/agent_diff.rs +++ b/crates/agent_ui/src/agent_diff.rs @@ -141,13 +141,13 @@ impl AgentDiffPane { paths_to_delete.remove(&path_key); let snapshot = buffer.read(cx).snapshot(); - let diff = diff_handle.read(cx); - let diff_hunk_ranges = diff + let diff_hunk_ranges = diff_handle + .read(cx) + .snapshot(cx) .hunks_intersecting_range( language::Anchor::min_max_range_for_buffer(snapshot.remote_id()), &snapshot, - cx, ) .map(|diff_hunk| diff_hunk.buffer_range.to_point(&snapshot)) .collect::>(); diff --git a/crates/buffer_diff/src/buffer_diff.rs b/crates/buffer_diff/src/buffer_diff.rs index e1c2a2a20b3858200d35074030b886b1a8d658f2..1b52f85ba37d3d607910720c86bc157a9e0cc995 100644 --- a/crates/buffer_diff/src/buffer_diff.rs +++ b/crates/buffer_diff/src/buffer_diff.rs @@ -1,14 +1,13 @@ use futures::channel::oneshot; use git2::{DiffLineType as GitDiffLineType, DiffOptions as GitOptions, Patch as GitPatch}; -use gpui::{App, AppContext as _, AsyncApp, Context, Entity, EventEmitter, Task, TaskLabel}; +use gpui::{App, AppContext as _, Context, Entity, EventEmitter, Task, TaskLabel}; use language::{ - BufferRow, DiffOptions, File, Language, LanguageName, LanguageRegistry, + BufferRow, Capability, DiffOptions, File, Language, LanguageName, LanguageRegistry, language_settings::language_settings, word_diff_ranges, }; use rope::Rope; use std::{ cmp::Ordering, - future::Future, iter, ops::Range, sync::{Arc, LazyLock}, @@ -1051,10 +1050,16 @@ impl EventEmitter for BufferDiff {} impl BufferDiff { pub fn new(buffer: &text::BufferSnapshot, cx: &mut App) -> Self { + let base_text = cx.new(|cx| { + let mut buffer = language::Buffer::local("", cx); + buffer.set_capability(Capability::ReadOnly, cx); + buffer + }); + BufferDiff { buffer_id: buffer.remote_id(), inner: BufferDiffInner { - base_text: cx.new(|cx| language::Buffer::local("", cx)), + base_text, hunks: SumTree::new(buffer), pending_hunks: SumTree::new(buffer), base_text_exists: false, @@ -1065,10 +1070,16 @@ impl BufferDiff { pub fn new_unchanged(buffer: &text::BufferSnapshot, cx: &mut Context) -> Self { let base_text = buffer.text(); + let base_text = cx.new(|cx| { + let mut buffer = language::Buffer::local(base_text, cx); + buffer.set_capability(Capability::ReadOnly, cx); + buffer + }); + BufferDiff { buffer_id: buffer.remote_id(), inner: BufferDiffInner { - base_text: cx.new(|cx| language::Buffer::local(base_text, cx)), + base_text, hunks: SumTree::new(buffer), pending_hunks: SumTree::new(buffer), base_text_exists: false, @@ -1193,11 +1204,6 @@ impl BufferDiff { diff_options, ); let base_text = base_text.unwrap_or_default(); - if cfg!(debug_assertions) { - for hunk in hunks.iter() { - base_text.get(hunk.diff_base_byte_range.clone()).unwrap(); - } - } BufferDiffInner { base_text, hunks, @@ -1207,7 +1213,18 @@ impl BufferDiff { }) } - pub fn language_changed(&mut self, cx: &mut Context) { + pub fn language_changed( + &mut self, + language: Option>, + language_registry: Option>, + cx: &mut Context, + ) { + self.inner.base_text.update(cx, |base_text, cx| { + base_text.set_language(language, cx); + if let Some(language_registry) = language_registry { + base_text.set_language_registry(language_registry); + } + }); cx.emit(BufferDiffEvent::LanguageChanged); } @@ -1234,6 +1251,7 @@ impl BufferDiff { ) -> Option> { log::debug!("set snapshot with secondary {secondary_diff_change:?}"); + dbg!(base_text_changed); let old_snapshot = self.snapshot(cx); let state = &mut self.inner; let (mut changed_range, mut base_text_changed_range) = @@ -1269,32 +1287,14 @@ impl BufferDiff { let state = &mut self.inner; state.base_text_exists = new_state.base_text_exists; - if cfg!(debug_assertions) { - for hunk in new_state.hunks.iter() { - new_state.base_text.get(hunk.diff_base_byte_range.clone()); - } - } if base_text_changed { state.base_text.update(cx, |base_text, cx| { - base_text.set_text(dbg!(new_state.base_text.clone()), cx); + base_text.set_capability(Capability::ReadWrite, cx); + base_text.set_text(new_state.base_text.clone(), cx); + base_text.set_capability(Capability::ReadOnly, cx); }) } state.hunks = new_state.hunks; - if cfg!(debug_assertions) { - pretty_assertions::assert_eq!( - state.base_text.read(cx).snapshot().text().as_str(), - new_state.base_text.as_ref() - ); - for hunk in state.hunks.iter() { - state - .base_text - .read(cx) - .snapshot() - .text_summary_for_range::( - hunk.diff_base_byte_range.clone(), - ); - } - } if base_text_changed || clear_pending_hunks { if let Some((first, last)) = state.pending_hunks.first().zip(state.pending_hunks.last()) { diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index b1ebdfe4ac6e07b3dc7730c07a6ecd71d067a6f6..c223f8d21667beec05ae3cc6764bf887d20dd424 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -11412,7 +11412,7 @@ impl Editor { let buffer = buffer.read(cx); let original_text = diff .read(cx) - .base_text() + .base_text(cx) .as_rope() .slice(hunk.diff_base_byte_range.start.0..hunk.diff_base_byte_range.end.0); let buffer_snapshot = buffer.snapshot(); diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 842cc4b78d9cbc0368bf50a341e7f889d659ae7a..9421d22695096c547fd6ea225d02a24cc5b5b2fb 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -19556,7 +19556,9 @@ async fn test_multibuffer_reverts(cx: &mut TestAppContext) { (buffer_2.clone(), base_text_2), (buffer_3.clone(), base_text_3), ] { - let diff = cx.new(|cx| BufferDiff::new_with_base_text(diff_base, &buffer, cx)); + let diff = cx.new(|cx| { + BufferDiff::new_with_base_text(diff_base, &buffer.read(cx).text_snapshot(), cx) + }); editor .buffer .update(cx, |buffer, cx| buffer.add_diff(diff, cx)); @@ -20181,7 +20183,9 @@ async fn test_toggle_diff_expand_in_multi_buffer(cx: &mut TestAppContext) { (buffer_2.clone(), file_2_old), (buffer_3.clone(), file_3_old), ] { - let diff = cx.new(|cx| BufferDiff::new_with_base_text(diff_base, &buffer, cx)); + let diff = cx.new(|cx| { + BufferDiff::new_with_base_text(diff_base, &buffer.read(cx).text_snapshot(), cx) + }); editor .buffer .update(cx, |buffer, cx| buffer.add_diff(diff, cx)); @@ -20287,7 +20291,9 @@ async fn test_expand_diff_hunk_at_excerpt_boundary(cx: &mut TestAppContext) { cx.add_window(|window, cx| Editor::new(EditorMode::full(), multi_buffer, None, window, cx)); editor .update(cx, |editor, _window, cx| { - let diff = cx.new(|cx| BufferDiff::new_with_base_text(base, &buffer, cx)); + let diff = cx.new(|cx| { + BufferDiff::new_with_base_text(base, &buffer.read(cx).text_snapshot(), cx) + }); editor .buffer .update(cx, |buffer, cx| buffer.add_diff(diff, cx)) @@ -21631,7 +21637,9 @@ async fn test_indent_guide_with_expanded_diff_hunks(cx: &mut TestAppContext) { editor.buffer().update(cx, |multibuffer, cx| { let buffer = multibuffer.as_singleton().unwrap(); - let diff = cx.new(|cx| BufferDiff::new_with_base_text(base_text, &buffer, cx)); + let diff = cx.new(|cx| { + BufferDiff::new_with_base_text(base_text, &buffer.read(cx).text_snapshot(), cx) + }); multibuffer.set_all_diff_hunks_expanded(cx); multibuffer.add_diff(diff, cx); diff --git a/crates/editor/src/split.rs b/crates/editor/src/split.rs index 96d6c70c900d2501c3e3d45bf3f3361fa178c533..2762ed1be4459bd8292a2d457f941575caecbf48 100644 --- a/crates/editor/src/split.rs +++ b/crates/editor/src/split.rs @@ -440,7 +440,9 @@ mod tests { HELLO! "}; let buffer = cx.new(|cx| Buffer::local(buffer_text, cx)); - let diff = cx.new(|cx| BufferDiff::new_with_base_text(base_text, &buffer, cx)); + let diff = cx.new(|cx| { + BufferDiff::new_with_base_text(base_text, &buffer.read(cx).text_snapshot(), cx) + }); let project = Project::test(FakeFs::new(cx.executor()), [], cx).await; let (workspace, cx) = cx.add_window_view(|window, cx| Workspace::test_new(project.clone(), window, cx)); diff --git a/crates/eval/src/example.rs b/crates/eval/src/example.rs index 84c47766e96948bccfc01f3b4472b5100c4b7b64..056e36f8330dd3c2c0d01c26653014637f7a2732 100644 --- a/crates/eval/src/example.rs +++ b/crates/eval/src/example.rs @@ -366,11 +366,12 @@ impl ExampleContext { let snapshot = buffer.read(cx).snapshot(); let file = snapshot.file().unwrap(); - let diff = diff.read(cx); - let base_text = diff.base_text().text(); + let base_text = diff.read(cx).base_text(cx).text(); let hunks = diff - .hunks(&snapshot, cx) + .read(cx) + .snapshot(cx) + .hunks(&snapshot) .map(|hunk| FileEditHunk { base_text: base_text[hunk.diff_base_byte_range.clone()].to_string(), text: snapshot diff --git a/crates/git_ui/src/commit_view.rs b/crates/git_ui/src/commit_view.rs index 60060a389eea47e8bbcde19b43c823d49f27091e..c4b01130a3440a6b985cac6457691dce7e308307 100644 --- a/crates/git_ui/src/commit_view.rs +++ b/crates/git_ui/src/commit_view.rs @@ -1,5 +1,5 @@ use anyhow::{Context as _, Result}; -use buffer_diff::{BufferDiff, BufferDiffSnapshot}; +use buffer_diff::{BufferDiff}; use editor::{Addon, Editor, EditorEvent, MultiBuffer}; use git::repository::{CommitDetails, CommitDiff, RepoPath}; use git::{GitHostingProviderRegistry, GitRemote, parse_git_remote_url}; @@ -195,7 +195,8 @@ impl CommitView { let snapshot = buffer.read(cx).snapshot(); let path = snapshot.file().unwrap().path().clone(); - let hunks: Vec<_> = buffer_diff.read(cx).hunks(&snapshot, cx).collect(); + let hunks: Vec<_> = + buffer_diff.read(cx).snapshot(cx).hunks(&snapshot).collect(); let excerpt_ranges = if hunks.is_empty() { vec![language::Point::zero()..snapshot.max_point()] @@ -796,35 +797,29 @@ async fn build_buffer_diff( LineEnding::normalize(old_text); } + let language = cx.update(|cx| buffer.read(cx).language().cloned())?; let buffer = cx.update(|cx| buffer.read(cx).snapshot())?; - let base_buffer = cx - .update(|cx| { - Buffer::build_snapshot( - old_text.as_deref().unwrap_or("").into(), - buffer.language().cloned(), - Some(language_registry.clone()), - cx, - ) - })? - .await; + let diff = cx.new(|cx| BufferDiff::new(&buffer.text, cx))?; - let diff_snapshot = cx - .update(|cx| { - BufferDiffSnapshot::new_with_base_buffer( + let update = diff + .update(cx, |diff, cx| { + diff.update_diff( buffer.text.clone(), - old_text.map(Arc::new), - base_buffer, + old_text.map(|old_text| Arc::from(old_text.as_str())), + true, + language.clone(), cx, ) })? .await; - cx.new(|cx| { - let mut diff = BufferDiff::new(&buffer.text, cx); - diff.set_snapshot(diff_snapshot, &buffer.text, cx); - diff - }) + diff.update(cx, |diff, cx| { + diff.language_changed(language, Some(language_registry.clone()), cx); + diff.set_snapshot(update, &buffer.text, true, cx) + }).ok(); + + Ok(diff) } impl EventEmitter for CommitView {} diff --git a/crates/git_ui/src/file_diff_view.rs b/crates/git_ui/src/file_diff_view.rs index e6ed8feb7f69493d3731d9d382cf9b955059fcc4..70f9140f17056ded72a48ca21a56ebe2e05c9592 100644 --- a/crates/git_ui/src/file_diff_view.rs +++ b/crates/git_ui/src/file_diff_view.rs @@ -1,14 +1,14 @@ //! FileDiffView provides a UI for displaying differences between two buffers. use anyhow::Result; -use buffer_diff::{BufferDiff, BufferDiffSnapshot}; +use buffer_diff::BufferDiff; use editor::{Editor, EditorEvent, MultiBuffer}; use futures::{FutureExt, select_biased}; use gpui::{ AnyElement, App, AppContext as _, AsyncApp, Context, Entity, EventEmitter, FocusHandle, Focusable, IntoElement, Render, Task, Window, }; -use language::Buffer; +use language::{Buffer, LanguageRegistry}; use project::Project; use std::{ any::{Any, TypeId}, @@ -52,8 +52,9 @@ impl FileDiffView { let new_buffer = project .update(cx, |project, cx| project.open_local_buffer(&new_path, cx))? .await?; + let languages = project.update(cx, |project, _| project.languages().clone())?; - let buffer_diff = build_buffer_diff(&old_buffer, &new_buffer, cx).await?; + let buffer_diff = build_buffer_diff(&old_buffer, &new_buffer, languages, cx).await?; workspace.update_in(cx, |workspace, window, cx| { let diff_view = cx.new(|cx| { @@ -143,19 +144,16 @@ impl FileDiffView { this.new_buffer.read(cx).snapshot(), ) })?; - let diff_snapshot = cx - .update(|cx| { - BufferDiffSnapshot::new_with_base_buffer( - new_snapshot.text.clone(), - Some(old_snapshot.text().into()), - old_snapshot, - cx, - ) - })? - .await; diff.update(cx, |diff, cx| { - diff.set_snapshot(diff_snapshot, &new_snapshot, cx) - })?; + diff.set_base_text( + Some(old_snapshot.text().as_str().into()), + old_snapshot.language().cloned(), + new_snapshot.text.clone(), + cx, + ) + })? + .await + .ok(); log::trace!("finish recalculating"); } Ok(()) @@ -167,27 +165,36 @@ impl FileDiffView { async fn build_buffer_diff( old_buffer: &Entity, new_buffer: &Entity, + language_registry: Arc, cx: &mut AsyncApp, ) -> Result> { let old_buffer_snapshot = old_buffer.read_with(cx, |buffer, _| buffer.snapshot())?; let new_buffer_snapshot = new_buffer.read_with(cx, |buffer, _| buffer.snapshot())?; - let diff_snapshot = cx - .update(|cx| { - BufferDiffSnapshot::new_with_base_buffer( + let diff = cx.new(|cx| BufferDiff::new(&new_buffer_snapshot.text, cx))?; + + let update = diff + .update(cx, |diff, cx| { + diff.update_diff( new_buffer_snapshot.text.clone(), Some(old_buffer_snapshot.text().into()), - old_buffer_snapshot, + true, + new_buffer_snapshot.language().cloned(), cx, ) })? .await; - cx.new(|cx| { - let mut diff = BufferDiff::new(&new_buffer_snapshot.text, cx); - diff.set_snapshot(diff_snapshot, &new_buffer_snapshot.text, cx); - diff - }) + diff.update(cx, |diff, cx| { + diff.language_changed( + new_buffer_snapshot.language().cloned(), + Some(language_registry), + cx, + ); + diff.set_snapshot(update, &new_buffer_snapshot.text, true, cx); + })?; + + Ok(diff) } impl EventEmitter for FileDiffView {} diff --git a/crates/git_ui/src/project_diff.rs b/crates/git_ui/src/project_diff.rs index 1dd6e7e3e35d28af6b3ac736610d497f07aa6e47..a726e8c7c4784cecd220164ea59283469f92839a 100644 --- a/crates/git_ui/src/project_diff.rs +++ b/crates/git_ui/src/project_diff.rs @@ -498,11 +498,11 @@ impl ProjectDiff { let snapshot = buffer.read(cx).snapshot(); let diff_read = diff.read(cx); - let diff_hunk_ranges = diff_read + let diff_snapshot = diff_read.snapshot(cx); + let diff_hunk_ranges = diff_snapshot .hunks_intersecting_range( Anchor::min_max_range_for_buffer(diff_read.buffer_id), &snapshot, - cx, ) .map(|diff_hunk| diff_hunk.buffer_range); let conflicts = conflict_addon diff --git a/crates/git_ui/src/text_diff_view.rs b/crates/git_ui/src/text_diff_view.rs index 5a8f0f79592f9161ae9c7ed7f0dc2814eacc2e53..a9a5ca2c24a30399838023433e68651c2a290052 100644 --- a/crates/git_ui/src/text_diff_view.rs +++ b/crates/git_ui/src/text_diff_view.rs @@ -1,7 +1,7 @@ //! TextDiffView currently provides a UI for displaying differences between the clipboard and selected text. use anyhow::Result; -use buffer_diff::{BufferDiff, BufferDiffSnapshot}; +use buffer_diff::BufferDiff; use editor::{Editor, EditorEvent, MultiBuffer, ToPoint, actions::DiffClipboardWithSelectionData}; use futures::{FutureExt, select_biased}; use gpui::{ @@ -257,23 +257,25 @@ async fn update_diff_buffer( cx: &mut AsyncApp, ) -> Result<()> { let source_buffer_snapshot = source_buffer.read_with(cx, |buffer, _| buffer.snapshot())?; + let language = source_buffer_snapshot.language().cloned(); let base_buffer_snapshot = clipboard_buffer.read_with(cx, |buffer, _| buffer.snapshot())?; let base_text = base_buffer_snapshot.text(); - let diff_snapshot = cx - .update(|cx| { - BufferDiffSnapshot::new_with_base_buffer( + let update = diff + .update(cx, |diff, cx| { + diff.update_diff( source_buffer_snapshot.text.clone(), - Some(Arc::new(base_text)), - base_buffer_snapshot, + Some(Arc::from(base_text.as_str())), + true, + language, cx, ) })? .await; diff.update(cx, |diff, cx| { - diff.set_snapshot(diff_snapshot, &source_buffer_snapshot.text, cx); + diff.set_snapshot(update, &source_buffer_snapshot.text, true, cx); })?; Ok(()) } diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 0079bda87523b4a3dd654d2480a22428153b7dbd..46d7f655627e1c01612b703a64bc0ab58d1b6669 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -3465,7 +3465,7 @@ impl BufferSnapshot { /// returned in chunks where each chunk has a single syntax highlighting style and /// diagnostic status. pub fn chunks(&self, range: Range, language_aware: bool) -> BufferChunks<'_> { - let range = dbg!(range.start.to_offset(self))..range.end.to_offset(self); + let range = range.start.to_offset(self)..range.end.to_offset(self); let mut syntax = None; if language_aware { diff --git a/crates/multi_buffer/src/multi_buffer.rs b/crates/multi_buffer/src/multi_buffer.rs index 5ebcdd62ce24f59e57bd45f941fa1cce702786d5..c6c0a5864105fabc91fe555d99665d6b4b913f19 100644 --- a/crates/multi_buffer/src/multi_buffer.rs +++ b/crates/multi_buffer/src/multi_buffer.rs @@ -2286,6 +2286,7 @@ impl MultiBuffer { diff: diff.snapshot(cx), main_buffer: None, }; + dbg!(); self.snapshot.get_mut().diffs.insert(buffer_id, diff); } @@ -2327,7 +2328,6 @@ impl MultiBuffer { let buffer = buffer_state.buffer.read(cx); let diff_change_range = range.to_offset(buffer); - dbg!(); let new_diff = DiffStateSnapshot { diff: diff.snapshot(cx), main_buffer: None, @@ -2338,6 +2338,7 @@ impl MultiBuffer { .get(&buffer_id) .is_none_or(|old_diff| !new_diff.base_texts_eq(old_diff)); + dbg!(); snapshot.diffs.insert_or_replace(buffer_id, new_diff); let mut excerpt_edits = Vec::new(); @@ -2376,7 +2377,7 @@ impl MultiBuffer { &mut snapshot, excerpt_edits, DiffChangeKind::DiffUpdated { - base_changed: dbg!(base_text_changed), + base_changed: base_text_changed, }, ); if !edits.is_empty() { @@ -3178,7 +3179,6 @@ impl MultiBuffer { let edit_new_start = MultiBufferOffset((edit_old_start.0 as isize + output_delta) as usize); - dbg!(); let changed_diff_hunks = Self::recompute_diff_transforms_for_edit( &edit, &mut excerpts, @@ -3314,6 +3314,7 @@ impl MultiBuffer { // Recompute the expanded hunks in the portion of the excerpt that // intersects the edit. if let Some(diff) = snapshot.diffs.get(&excerpt.buffer_id) { + dbg!(); let buffer = &excerpt.buffer; let excerpt_start = *excerpts.start(); let excerpt_end = excerpt_start + excerpt.text_summary.len; @@ -3417,19 +3418,13 @@ impl MultiBuffer { excerpt.id ); - if !hunk.diff_base_byte_range.is_empty() + if dbg!(!hunk.diff_base_byte_range.is_empty()) && hunk_buffer_range.start >= edit_buffer_start && hunk_buffer_range.start <= excerpt_buffer_end - && snapshot.show_deleted_hunks + && dbg!(snapshot.show_deleted_hunks) { - dbg!(&hunk.diff_base_byte_range); + dbg!(); let base_text = diff.base_text(); - if cfg!(debug_assertions) { - dbg!(); - base_text.text_summary_for_range::( - hunk.diff_base_byte_range.clone(), - ); - } let mut text_cursor = base_text.as_rope().cursor(hunk.diff_base_byte_range.start); let mut base_text_summary = text_cursor @@ -7856,7 +7851,6 @@ impl<'a> Iterator for MultiBufferChunks<'a> { has_trailing_newline, .. } => { - dbg!(&base_text_byte_range); let base_text_start = base_text_byte_range.start + (self.range.start - diff_transform_start); let base_text_end = @@ -7875,10 +7869,7 @@ impl<'a> Iterator for MultiBufferChunks<'a> { chunks } else { let base_buffer = &self.diffs.get(buffer_id)?.base_text(); - base_buffer.chunks( - dbg!(base_text_start)..dbg!(base_text_end), - self.language_aware, - ) + base_buffer.chunks(base_text_start..base_text_end, self.language_aware) }; let chunk = if let Some(chunk) = chunks.next() { diff --git a/crates/project/src/git_store.rs b/crates/project/src/git_store.rs index 34c82216f0f8b3bdbf593cbe568dd531e0bc7e3d..2d1b14c2e29e71106bf6d815de845824c0f21d76 100644 --- a/crates/project/src/git_store.rs +++ b/crates/project/src/git_store.rs @@ -819,6 +819,7 @@ impl GitStore { cx.subscribe(&diff, Self::on_buffer_diff_event).detach(); diff_state.update(cx, |diff_state, cx| { + diff_state.language_changed = true; diff_state.language = language; diff_state.language_registry = language_registry; @@ -3119,7 +3120,7 @@ impl BufferGitState { { unstaged_diff.update(cx, |diff, cx| { if language_changed { - diff.language_changed(cx); + diff.language_changed(language.clone(), language_registry.clone(), cx); } diff.set_snapshot(new_unstaged_diff, &buffer, index_changed, cx) })? @@ -3134,7 +3135,7 @@ impl BufferGitState { { uncommitted_diff.update(cx, |diff, cx| { if language_changed { - diff.language_changed(cx); + diff.language_changed(language, language_registry, cx); } diff.set_snapshot_with_secondary( new_uncommitted_diff, diff --git a/crates/project/src/project_tests.rs b/crates/project/src/project_tests.rs index 0387358f1b6acee6ac9382467d438bf1454a8632..38ba22a467244f4ec3be039b0103b41b3b29ca02 100644 --- a/crates/project/src/project_tests.rs +++ b/crates/project/src/project_tests.rs @@ -7222,9 +7222,9 @@ async fn test_unstaged_diff_for_buffer(cx: &mut gpui::TestAppContext) { unstaged_diff.update(cx, |unstaged_diff, cx| { let snapshot = buffer.read(cx).snapshot(); assert_hunks( - unstaged_diff.hunks(&snapshot, cx), + unstaged_diff.snapshot(cx).hunks(&snapshot), &snapshot, - &unstaged_diff.base_text_string().unwrap(), + &unstaged_diff.base_text_string(cx).unwrap(), &[ (0..1, "", "// print goodbye\n", DiffHunkStatus::added_none()), ( @@ -7250,9 +7250,11 @@ async fn test_unstaged_diff_for_buffer(cx: &mut gpui::TestAppContext) { unstaged_diff.update(cx, |unstaged_diff, cx| { let snapshot = buffer.read(cx).snapshot(); assert_hunks( - unstaged_diff.hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &snapshot, cx), + unstaged_diff + .snapshot(cx) + .hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &snapshot), &snapshot, - &unstaged_diff.base_text().text(), + &unstaged_diff.base_text(cx).text(), &[( 2..3, "", @@ -7332,16 +7334,17 @@ async fn test_uncommitted_diff_for_buffer(cx: &mut gpui::TestAppContext) { }) .await .unwrap(); - diff_1.read_with(cx, |diff, _| { - assert_eq!(diff.base_text().language().cloned(), Some(language)) + diff_1.read_with(cx, |diff, cx| { + assert_eq!(diff.base_text(cx).language().cloned(), Some(language)) }); cx.run_until_parked(); diff_1.update(cx, |diff, cx| { let snapshot = buffer_1.read(cx).snapshot(); assert_hunks( - diff.hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &snapshot, cx), + diff.snapshot(cx) + .hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &snapshot), &snapshot, - &diff.base_text_string().unwrap(), + &diff.base_text_string(cx).unwrap(), &[ ( 0..1, @@ -7380,9 +7383,10 @@ async fn test_uncommitted_diff_for_buffer(cx: &mut gpui::TestAppContext) { diff_1.update(cx, |diff, cx| { let snapshot = buffer_1.read(cx).snapshot(); assert_hunks( - diff.hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &snapshot, cx), + diff.snapshot(cx) + .hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &snapshot), &snapshot, - &diff.base_text().text(), + &diff.base_text(cx).text(), &[( 2..3, "", @@ -7409,9 +7413,10 @@ async fn test_uncommitted_diff_for_buffer(cx: &mut gpui::TestAppContext) { diff_2.update(cx, |diff, cx| { let snapshot = buffer_2.read(cx).snapshot(); assert_hunks( - diff.hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &snapshot, cx), + diff.snapshot(cx) + .hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &snapshot), &snapshot, - &diff.base_text_string().unwrap(), + &diff.base_text_string(cx).unwrap(), &[( 0..0, "// the-deleted-contents\n", @@ -7430,9 +7435,10 @@ async fn test_uncommitted_diff_for_buffer(cx: &mut gpui::TestAppContext) { diff_2.update(cx, |diff, cx| { let snapshot = buffer_2.read(cx).snapshot(); assert_hunks( - diff.hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &snapshot, cx), + diff.snapshot(cx) + .hunks_intersecting_range(Anchor::MIN..Anchor::MAX, &snapshot), &snapshot, - &diff.base_text_string().unwrap(), + &diff.base_text_string(cx).unwrap(), &[( 0..0, "// the-deleted-contents\n", @@ -7501,9 +7507,9 @@ async fn test_staging_hunks(cx: &mut gpui::TestAppContext) { // The hunks are initially unstaged. uncommitted_diff.read_with(cx, |diff, cx| { assert_hunks( - diff.hunks(&snapshot, cx), + diff.snapshot(cx).hunks(&snapshot), &snapshot, - &diff.base_text_string().unwrap(), + &diff.base_text_string(cx).unwrap(), &[ ( 0..0, @@ -7532,14 +7538,15 @@ async fn test_staging_hunks(cx: &mut gpui::TestAppContext) { let range = snapshot.anchor_before(Point::new(1, 0))..snapshot.anchor_before(Point::new(2, 0)); let hunks = diff - .hunks_intersecting_range(range, &snapshot, cx) + .snapshot(cx) + .hunks_intersecting_range(range, &snapshot) .collect::>(); diff.stage_or_unstage_hunks(true, &hunks, &snapshot, true, cx); assert_hunks( - diff.hunks(&snapshot, cx), + diff.snapshot(cx).hunks(&snapshot), &snapshot, - &diff.base_text_string().unwrap(), + &diff.base_text_string(cx).unwrap(), &[ ( 0..0, @@ -7584,9 +7591,9 @@ async fn test_staging_hunks(cx: &mut gpui::TestAppContext) { cx.run_until_parked(); uncommitted_diff.update(cx, |diff, cx| { assert_hunks( - diff.hunks(&snapshot, cx), + diff.snapshot(cx).hunks(&snapshot), &snapshot, - &diff.base_text_string().unwrap(), + &diff.base_text_string(cx).unwrap(), &[ ( 0..0, @@ -7634,14 +7641,15 @@ async fn test_staging_hunks(cx: &mut gpui::TestAppContext) { let range = snapshot.anchor_before(Point::new(3, 0))..snapshot.anchor_before(Point::new(4, 0)); let hunks = diff - .hunks_intersecting_range(range, &snapshot, cx) + .snapshot(cx) + .hunks_intersecting_range(range, &snapshot) .collect::>(); diff.stage_or_unstage_hunks(true, &hunks, &snapshot, true, cx); assert_hunks( - diff.hunks(&snapshot, cx), + diff.snapshot(cx).hunks(&snapshot), &snapshot, - &diff.base_text_string().unwrap(), + &diff.base_text_string(cx).unwrap(), &[ ( 0..0, @@ -7684,9 +7692,9 @@ async fn test_staging_hunks(cx: &mut gpui::TestAppContext) { cx.run_until_parked(); uncommitted_diff.update(cx, |diff, cx| { assert_hunks( - diff.hunks(&snapshot, cx), + diff.snapshot(cx).hunks(&snapshot), &snapshot, - &diff.base_text_string().unwrap(), + &diff.base_text_string(cx).unwrap(), &[ ( 0..0, @@ -7727,7 +7735,7 @@ async fn test_staging_hunks(cx: &mut gpui::TestAppContext) { // Stage two hunks with separate operations. uncommitted_diff.update(cx, |diff, cx| { - let hunks = diff.hunks(&snapshot, cx).collect::>(); + let hunks = diff.snapshot(cx).hunks(&snapshot).collect::>(); diff.stage_or_unstage_hunks(true, &hunks[0..1], &snapshot, true, cx); diff.stage_or_unstage_hunks(true, &hunks[2..3], &snapshot, true, cx); }); @@ -7915,7 +7923,7 @@ async fn test_staging_hunks_with_delayed_fs_event(cx: &mut gpui::TestAppContext) let hunk = diff.snapshot(cx).hunks(&snapshot).nth(1).unwrap(); diff.stage_or_unstage_hunks(true, &[hunk], &snapshot, true, cx); assert_hunks( - diff.hunks(&snapshot, cx), + diff.snapshot(cx).hunks(&snapshot), &snapshot, &diff.base_text_string(cx).unwrap(), &[ @@ -7947,7 +7955,7 @@ async fn test_staging_hunks_with_delayed_fs_event(cx: &mut gpui::TestAppContext) // Stage the third hunk before receiving the second FS event. uncommitted_diff.update(cx, |diff, cx| { - let hunk = diff.hunks(&snapshot, cx).nth(2).unwrap(); + let hunk = diff.snapshot(cx).hunks(&snapshot).nth(2).unwrap(); diff.stage_or_unstage_hunks(true, &[hunk], &snapshot, true, cx); }); @@ -7959,7 +7967,7 @@ async fn test_staging_hunks_with_delayed_fs_event(cx: &mut gpui::TestAppContext) cx.run_until_parked(); uncommitted_diff.update(cx, |diff, cx| { assert_hunks( - diff.hunks(&snapshot, cx), + diff.snapshot(cx).hunks(&snapshot), &snapshot, &diff.base_text_string(cx).unwrap(), &[ @@ -8045,8 +8053,9 @@ async fn test_staging_random_hunks( .await .unwrap(); - let mut hunks = - uncommitted_diff.update(cx, |diff, cx| diff.hunks(&snapshot, cx).collect::>()); + let mut hunks = uncommitted_diff.update(cx, |diff, cx| { + diff.snapshot(cx).hunks(&snapshot).collect::>() + }); assert_eq!(hunks.len(), 6); for _i in 0..operations { @@ -8097,7 +8106,8 @@ async fn test_staging_random_hunks( .map(|hunk| (hunk.range.start.row, hunk.secondary_status)) .collect::>(); let actual_hunks = diff - .hunks(&snapshot, cx) + .snapshot(cx) + .hunks(&snapshot) .map(|hunk| (hunk.range.start.row, hunk.secondary_status)) .collect::>(); assert_eq!(actual_hunks, expected_hunks); @@ -8162,7 +8172,7 @@ async fn test_single_file_diffs(cx: &mut gpui::TestAppContext) { uncommitted_diff.update(cx, |uncommitted_diff, cx| { let snapshot = buffer.read(cx).snapshot(); assert_hunks( - uncommitted_diff.hunks(&snapshot, cx), + uncommitted_diff.snapshot(cx).hunks(&snapshot), &snapshot, &uncommitted_diff.base_text_string(cx).unwrap(), &[( @@ -8227,7 +8237,7 @@ async fn test_staging_hunk_preserve_executable_permission(cx: &mut gpui::TestApp .unwrap(); uncommitted_diff.update(cx, |diff, cx| { - let hunks = diff.hunks(&snapshot, cx).collect::>(); + let hunks = diff.snapshot(cx).hunks(&snapshot).collect::>(); diff.stage_or_unstage_hunks(true, &hunks, &snapshot, true, cx); }); @@ -10344,7 +10354,7 @@ async fn test_buffer_changed_file_path_updates_git_diff(cx: &mut gpui::TestAppCo cx.run_until_parked(); - unstaged_diff.update(cx, |unstaged_diff, _cx| { + unstaged_diff.update(cx, |unstaged_diff, cx| { let base_text = unstaged_diff.base_text_string(cx).unwrap(); assert_eq!(base_text, file_1_staged, "Should start with file_1 staged"); }); @@ -10375,7 +10385,7 @@ async fn test_buffer_changed_file_path_updates_git_diff(cx: &mut gpui::TestAppCo "Diff bases should be automatically updated to file_2 staged content" ); - let hunks: Vec<_> = unstaged_diff.hunks(&snapshot, cx).collect(); + let hunks: Vec<_> = unstaged_diff.snapshot(cx).hunks(&snapshot).collect(); assert!(!hunks.is_empty(), "Should have diff hunks for file_2"); }); @@ -10388,7 +10398,7 @@ async fn test_buffer_changed_file_path_updates_git_diff(cx: &mut gpui::TestAppCo cx.run_until_parked(); - uncommitted_diff.update(cx, |uncommitted_diff, _cx| { + uncommitted_diff.update(cx, |uncommitted_diff, cx| { let base_text = uncommitted_diff.base_text_string(cx).unwrap(); assert_eq!( base_text, file_2_committed, diff --git a/crates/remote_server/src/remote_editing_tests.rs b/crates/remote_server/src/remote_editing_tests.rs index 1e6ecddb5f2599a0ded0180f3afd3df0f197f037..78d17694e228600021d8345196dec38ef0c65ee6 100644 --- a/crates/remote_server/src/remote_editing_tests.rs +++ b/crates/remote_server/src/remote_editing_tests.rs @@ -96,8 +96,11 @@ async fn test_basic_remote_editing(cx: &mut TestAppContext, server_cx: &mut Test .await .unwrap(); - diff.update(cx, |diff, _| { - assert_eq!(diff.base_text_string().unwrap(), "fn one() -> usize { 0 }"); + diff.update(cx, |diff, cx| { + assert_eq!( + diff.base_text_string(cx).unwrap(), + "fn one() -> usize { 0 }" + ); }); buffer.update(cx, |buffer, cx| { @@ -157,9 +160,9 @@ async fn test_basic_remote_editing(cx: &mut TestAppContext, server_cx: &mut Test &[("src/lib2.rs", "fn one() -> usize { 100 }".into())], ); cx.executor().run_until_parked(); - diff.update(cx, |diff, _| { + diff.update(cx, |diff, cx| { assert_eq!( - diff.base_text_string().unwrap(), + diff.base_text_string(cx).unwrap(), "fn one() -> usize { 100 }" ); }); @@ -1443,12 +1446,12 @@ async fn test_remote_git_diffs(cx: &mut TestAppContext, server_cx: &mut TestAppC .unwrap(); diff.read_with(cx, |diff, cx| { - assert_eq!(diff.base_text_string().unwrap(), text_1); + assert_eq!(diff.base_text_string(cx).unwrap(), text_1); assert_eq!( diff.secondary_diff() .unwrap() .read(cx) - .base_text_string() + .base_text_string(cx) .unwrap(), text_1 ); @@ -1462,12 +1465,12 @@ async fn test_remote_git_diffs(cx: &mut TestAppContext, server_cx: &mut TestAppC cx.executor().run_until_parked(); diff.read_with(cx, |diff, cx| { - assert_eq!(diff.base_text_string().unwrap(), text_1); + assert_eq!(diff.base_text_string(cx).unwrap(), text_1); assert_eq!( diff.secondary_diff() .unwrap() .read(cx) - .base_text_string() + .base_text_string(cx) .unwrap(), text_2 ); @@ -1482,12 +1485,12 @@ async fn test_remote_git_diffs(cx: &mut TestAppContext, server_cx: &mut TestAppC cx.executor().run_until_parked(); diff.read_with(cx, |diff, cx| { - assert_eq!(diff.base_text_string().unwrap(), text_2); + assert_eq!(diff.base_text_string(cx).unwrap(), text_2); assert_eq!( diff.secondary_diff() .unwrap() .read(cx) - .base_text_string() + .base_text_string(cx) .unwrap(), text_2 ); @@ -1588,12 +1591,12 @@ async fn test_remote_git_diffs_when_recv_update_repository_delay( .unwrap(); diff.read_with(cx, |diff, cx| { - assert_eq!(diff.base_text_string().unwrap(), text_1); + assert_eq!(diff.base_text_string(cx).unwrap(), text_1); assert_eq!( diff.secondary_diff() .unwrap() .read(cx) - .base_text_string() + .base_text_string(cx) .unwrap(), text_1 ); @@ -1607,12 +1610,12 @@ async fn test_remote_git_diffs_when_recv_update_repository_delay( cx.executor().run_until_parked(); diff.read_with(cx, |diff, cx| { - assert_eq!(diff.base_text_string().unwrap(), text_1); + assert_eq!(diff.base_text_string(cx).unwrap(), text_1); assert_eq!( diff.secondary_diff() .unwrap() .read(cx) - .base_text_string() + .base_text_string(cx) .unwrap(), text_2 ); @@ -1627,12 +1630,12 @@ async fn test_remote_git_diffs_when_recv_update_repository_delay( cx.executor().run_until_parked(); diff.read_with(cx, |diff, cx| { - assert_eq!(diff.base_text_string().unwrap(), text_2); + assert_eq!(diff.base_text_string(cx).unwrap(), text_2); assert_eq!( diff.secondary_diff() .unwrap() .read(cx) - .base_text_string() + .base_text_string(cx) .unwrap(), text_2 ); diff --git a/crates/rope/src/chunk.rs b/crates/rope/src/chunk.rs index fc6d7aa7886a5094b4af966bf0ca858718e60a99..4cb3c74d011cf44c3cdeb00f22a854783405d334 100644 --- a/crates/rope/src/chunk.rs +++ b/crates/rope/src/chunk.rs @@ -132,7 +132,6 @@ impl Chunk { return true; } if PANIC || cfg!(debug_assertions) { - dbg!(offset); panic_char_boundary(&self.text, offset); } else { log_err_char_boundary(&self.text, offset); diff --git a/crates/zeta/src/rate_prediction_modal.rs b/crates/zeta/src/rate_prediction_modal.rs index 0cceb86608ed609122c81d406c71280894789e88..c5404c6e9ed694aed9cf1944bf9826f08bfae137 100644 --- a/crates/zeta/src/rate_prediction_modal.rs +++ b/crates/zeta/src/rate_prediction_modal.rs @@ -319,22 +319,23 @@ impl RatePredictionsModal { let start = Point::new(range.start.row.saturating_sub(5), 0); let end = Point::new(range.end.row + 5, 0).min(new_buffer_snapshot.max_point()); - let diff = cx.new::(|cx| { - let diff_snapshot = BufferDiffSnapshot::new_with_base_buffer( + let language = new_buffer_snapshot.language().cloned(); + let diff = cx.new(|cx| BufferDiff::new(&new_buffer_snapshot.text, cx)); + diff.update(cx, |diff, cx| { + let update = diff.update_diff( new_buffer_snapshot.text.clone(), Some(old_buffer_snapshot.text().into()), - old_buffer_snapshot.clone(), + true, + language, cx, ); - let diff = BufferDiff::new(&new_buffer_snapshot, cx); cx.spawn(async move |diff, cx| { - let diff_snapshot = diff_snapshot.await; + let update = update.await; diff.update(cx, |diff, cx| { - diff.set_snapshot(diff_snapshot, &new_buffer_snapshot.text, cx); + diff.set_snapshot(update, &new_buffer_snapshot.text, true, cx); }) }) .detach(); - diff }); editor.disable_header_for_buffer(new_buffer_id, cx);