From 92876345482861b794b9797c3babd101cc74fa05 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Wed, 7 Jun 2023 18:59:39 +0300 Subject: [PATCH] Prepare to find diffs between inlay hint generations --- crates/editor/src/display_map.rs | 19 ++++- .../src/display_map/editor_addition_map.rs | 78 ++++++++++++++++--- 2 files changed, 85 insertions(+), 12 deletions(-) diff --git a/crates/editor/src/display_map.rs b/crates/editor/src/display_map.rs index a870b70f7b..e34d919164 100644 --- a/crates/editor/src/display_map.rs +++ b/crates/editor/src/display_map.rs @@ -288,13 +288,28 @@ impl DisplayMap { .update(cx, |map, cx| map.set_wrap_width(width, cx)) } - pub fn set_inlay_hints(&self, new_hints: &[project::InlayHint], cx: &mut ModelContext) { + pub fn set_inlay_hints( + &mut self, + new_hints: &[project::InlayHint], + cx: &mut ModelContext, + ) { + dbg!("---", new_hints.len()); let multi_buffer = self.buffer.read(cx); + + let zz = dbg!(multi_buffer + .all_buffers() + .into_iter() + .map(|buffer_handle| buffer_handle.id()) + .collect::>()); + self.editor_addition_map.set_inlay_hints( new_hints .into_iter() .filter_map(|hint| { - let buffer = multi_buffer.buffer(hint.buffer_id)?.read(cx); + // TODO kb this is all wrong, need to manage both(?) or at least the remote buffer id when needed. + // Here though, `.buffer(` requires remote buffer id, so use the workaround above. + dbg!(zz.contains(&(hint.buffer_id as usize))); + let buffer = dbg!(multi_buffer.buffer(dbg!(hint.buffer_id)))?.read(cx); let snapshot = buffer.snapshot(); Some(InlayHintToRender { position: editor_addition_map::EditorAdditionPoint( diff --git a/crates/editor/src/display_map/editor_addition_map.rs b/crates/editor/src/display_map/editor_addition_map.rs index 63c65e5405..4f88610f44 100644 --- a/crates/editor/src/display_map/editor_addition_map.rs +++ b/crates/editor/src/display_map/editor_addition_map.rs @@ -1,7 +1,10 @@ #![allow(unused)] // TODO kb -use std::ops::{Add, AddAssign, Range, Sub}; +use std::{ + ops::{Add, AddAssign, Range, Sub}, + sync::atomic::{self, AtomicUsize}, +}; use crate::MultiBufferSnapshot; @@ -12,21 +15,43 @@ use super::{ }, TextHighlights, }; +use collections::HashMap; use gpui::fonts::HighlightStyle; use language::{Chunk, Edit, Point, Rope, TextSummary}; use parking_lot::Mutex; use project::InlayHint; use rand::Rng; -use sum_tree::Bias; +use sum_tree::{Bias, SumTree}; -pub struct EditorAdditionMap(Mutex); +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct InlayHintId(usize); + +pub struct EditorAdditionMap { + snapshot: Mutex, + next_hint_id: AtomicUsize, + hints: HashMap, +} #[derive(Clone)] pub struct EditorAdditionSnapshot { // TODO kb merge these two together pub suggestion_snapshot: SuggestionSnapshot, + transforms: SumTree, pub version: usize, - hints: Vec, +} + +#[derive(Clone)] +struct Transform { + input: TextSummary, + output: TextSummary, +} + +impl sum_tree::Item for Transform { + type Summary = TextSummary; + + fn summary(&self) -> Self::Summary { + self.output.clone() + } } pub type EditorAdditionEdit = Edit; @@ -68,7 +93,7 @@ pub struct EditorAdditionChunks<'a> { suggestion_chunks: SuggestionChunks<'a>, } -#[derive(Clone)] +#[derive(Debug, Clone)] pub struct InlayHintToRender { pub(super) position: EditorAdditionPoint, pub(super) text: Rope, @@ -109,9 +134,17 @@ impl EditorAdditionMap { let snapshot = EditorAdditionSnapshot { suggestion_snapshot: suggestion_snapshot.clone(), version: 0, - hints: Vec::new(), + transforms: SumTree::new(), }; - (Self(Mutex::new(snapshot.clone())), snapshot) + + ( + Self { + snapshot: Mutex::new(snapshot.clone()), + next_hint_id: AtomicUsize::new(0), + hints: HashMap::default(), + }, + snapshot, + ) } pub fn sync( @@ -119,13 +152,15 @@ impl EditorAdditionMap { suggestion_snapshot: SuggestionSnapshot, suggestion_edits: Vec, ) -> (EditorAdditionSnapshot, Vec) { - let mut snapshot = self.0.lock(); + let mut snapshot = self.snapshot.lock(); if snapshot.suggestion_snapshot.version != suggestion_snapshot.version { snapshot.version += 1; } let mut editor_addition_edits = Vec::new(); + + dbg!(&suggestion_edits); for suggestion_edit in suggestion_edits { let old = suggestion_edit.old; let new = suggestion_edit.new; @@ -141,8 +176,31 @@ impl EditorAdditionMap { (snapshot.clone(), editor_addition_edits) } - pub fn set_inlay_hints(&self, new_hints: Vec) { - self.0.lock().hints = new_hints; + // TODO kb replace set_inlay_hints with this + pub fn splice( + &mut self, + to_remove: Vec, + to_insert: Vec, + ) -> Vec { + // Order removals and insertions by position. + // let anchors; + + // Remove and insert inlays in a single traversal across the tree. + todo!("TODO kb") + } + + pub fn set_inlay_hints(&mut self, new_hints: Vec) { + dbg!(new_hints.len()); + // TODO kb reuse ids for hints that did not change and similar things + self.hints = new_hints + .into_iter() + .map(|hint| { + ( + InlayHintId(self.next_hint_id.fetch_add(1, atomic::Ordering::SeqCst)), + hint, + ) + }) + .collect(); } }