From 9ce9b738793be54cd8b7f8254d74a7748ed933de Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 9 Jun 2023 13:21:15 +0300 Subject: [PATCH] Generate edits for inlay hints Co-Authored-By: Antonio Scandurra --- crates/editor/src/display_map.rs | 30 ++++++++++++++++------ crates/editor/src/display_map/inlay_map.rs | 28 +++++++++++++++----- crates/editor/src/editor.rs | 2 +- 3 files changed, 45 insertions(+), 15 deletions(-) diff --git a/crates/editor/src/display_map.rs b/crates/editor/src/display_map.rs index 5644d63c37b1eb61f6cf6afa311cf5715db5cd8d..9a7178e1954fddd861a52b185ff5d90263b3d90a 100644 --- a/crates/editor/src/display_map.rs +++ b/crates/editor/src/display_map.rs @@ -285,20 +285,29 @@ impl DisplayMap { .update(cx, |map, cx| map.set_wrap_width(width, cx)) } - pub fn splice_inlay_hints( + pub fn splice_inlays( &mut self, new_hints: &HashMap>, cx: &mut ModelContext, ) { - let multi_buffer = self.buffer.read(cx); - let multi_snapshot = multi_buffer.snapshot(cx); + let buffer_snapshot = self.buffer.read(cx).snapshot(cx); + let edits = self.buffer_subscription.consume().into_inner(); + let tab_size = Self::tab_size(&self.buffer, cx); + let (snapshot, edits) = self.fold_map.read(buffer_snapshot.clone(), edits); + let (snapshot, edits) = self.suggestion_map.sync(snapshot, edits); + let (snapshot, edits) = self.inlay_map.sync(snapshot, edits); + let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size); + let (snapshot, edits) = self + .wrap_map + .update(cx, |map, cx| map.sync(snapshot, edits, cx)); + self.block_map.read(snapshot, edits); - let mut hints_to_add = Vec::new(); + let mut new_inlays = Vec::new(); for (&location, hints) in new_hints { for hint in hints { let hint_anchor = - multi_snapshot.anchor_in_excerpt(location.excerpt_id, hint.position); - hints_to_add.push(( + buffer_snapshot.anchor_in_excerpt(location.excerpt_id, hint.position); + new_inlays.push(( location, InlayProperties { position: hint_anchor, @@ -308,11 +317,16 @@ impl DisplayMap { } } - self.inlay_map.splice( + let (snapshot, edits, _) = self.inlay_map.splice( // TODO kb this is wrong, calc diffs in the editor instead. self.inlay_map.inlays.keys().copied().collect(), - hints_to_add, + new_inlays, ); + let (snapshot, edits) = self.tab_map.sync(snapshot, edits, tab_size); + let (snapshot, edits) = self + .wrap_map + .update(cx, |map, cx| map.sync(snapshot, edits, cx)); + self.block_map.read(snapshot, edits); } fn tab_size(buffer: &ModelHandle, cx: &mut ModelContext) -> NonZeroU32 { diff --git a/crates/editor/src/display_map/inlay_map.rs b/crates/editor/src/display_map/inlay_map.rs index 66be89b5e48b6d6b105ba7dfaf4b9367041a119e..c2b5dcc0d240b807c8f6932d91a0ee59b529e9cc 100644 --- a/crates/editor/src/display_map/inlay_map.rs +++ b/crates/editor/src/display_map/inlay_map.rs @@ -23,6 +23,7 @@ use parking_lot::Mutex; use project::InlayHint; use rand::Rng; use sum_tree::{Bias, Cursor, SumTree}; +use text::Patch; use util::post_inc; #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -372,10 +373,11 @@ impl InlayMap { } } + let mut inlay_edits = Patch::default(); let mut new_transforms = SumTree::new(); let mut cursor = snapshot .transforms - .cursor::<(InlayPoint, SuggestionPoint)>(); + .cursor::<(InlayPoint, (SuggestionPoint, InlayOffset))>(); for ((inlay_point, inlay_id), inlay) in inlays { new_transforms.push_tree(cursor.slice(&inlay_point, Bias::Right, &()), &()); while let Some(transform) = cursor.item() { @@ -387,6 +389,11 @@ impl InlayMap { cursor.next(&()); } else { if inlay.id == inlay_id.0 { + let new_start = InlayOffset(new_transforms.summary().output.len); + inlay_edits.push(Edit { + old: cursor.start().1 .1..cursor.end(&()).1 .1, + new: new_start..new_start, + }); cursor.next(&()); } break; @@ -396,11 +403,14 @@ impl InlayMap { } if let Some(inlay) = inlay { + let new_start = InlayOffset(new_transforms.summary().output.len); + let new_end = InlayOffset(new_start.0 + inlay.properties.text.len()); if let Some(Transform::Isomorphic(transform)) = cursor.item() { let prefix = inlay_point.0 - cursor.start().0 .0; if !prefix.is_zero() { - let prefix_suggestion_start = cursor.start().1; - let prefix_suggestion_end = SuggestionPoint(cursor.start().1 .0 + prefix); + let prefix_suggestion_start = cursor.start().1 .0; + let prefix_suggestion_end = + SuggestionPoint(cursor.start().1 .0 .0 + prefix); new_transforms.push( Transform::Isomorphic( snapshot.suggestion_snapshot.text_summary_for_range( @@ -413,8 +423,8 @@ impl InlayMap { new_transforms.push(Transform::Inlay(inlay), &()); - let suffix_suggestion_start = SuggestionPoint(cursor.start().1 .0 + prefix); - let suffix_suggestion_end = cursor.end(&()).1; + let suffix_suggestion_start = SuggestionPoint(cursor.start().1 .0 .0 + prefix); + let suffix_suggestion_end = cursor.end(&()).1 .0; new_transforms.push( Transform::Isomorphic(snapshot.suggestion_snapshot.text_summary_for_range( suffix_suggestion_start..suffix_suggestion_end, @@ -426,6 +436,12 @@ impl InlayMap { } else { new_transforms.push(Transform::Inlay(inlay), &()); } + + let old_start = snapshot.to_offset(inlay_point); + inlay_edits.push(Edit { + old: old_start..old_start, + new: new_start..new_end, + }); } } @@ -434,7 +450,7 @@ impl InlayMap { snapshot.transforms = new_transforms; snapshot.version += 1; - (snapshot.clone(), Vec::new(), new_ids) + (snapshot.clone(), inlay_edits.into_inner(), new_ids) } } diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 9560aa707e043bea70820b7f1c2750b6ed174a1f..b73a02d9c39959e05ee94d2224e825e983de1ea5 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -2702,7 +2702,7 @@ impl Editor { editor .update(&mut cx, |editor, cx| { editor.display_map.update(cx, |display_map, cx| { - display_map.splice_inlay_hints(&new_hints, cx); + display_map.splice_inlays(&new_hints, cx); }); }) .log_err()