Compare commits
2 Commits
v0.217.0-p
...
skipped-hu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8fe49b372 | ||
|
|
f1c36ba9ae |
@@ -565,6 +565,15 @@ impl DisplayMap {
|
||||
self.inlay_map.current_inlays()
|
||||
}
|
||||
|
||||
// pub(crate) fn sync_unsplittable_groups(&mut self) {
|
||||
// let group_boundaries = /* read diff hunk info from self */;
|
||||
// self.splice_unsplittable_groups(group_boundaries);
|
||||
// }
|
||||
|
||||
// fn splice_unsplittable_groups(&mut self, group_boundaries: Vec<usize>) {
|
||||
|
||||
// }
|
||||
|
||||
pub(crate) fn splice_inlays(
|
||||
&mut self,
|
||||
to_remove: &[InlayId],
|
||||
|
||||
@@ -507,6 +507,55 @@ impl BlockMap {
|
||||
BlockMapWriter(self)
|
||||
}
|
||||
|
||||
// current problem: how do we know how many spacer lines?
|
||||
|
||||
// q: which buffer row if any does this wrap row end? log(n)
|
||||
// iterate over buffer rows; for each one, translate into a wrap row and seek to that wrap row
|
||||
// q: for a given buffer row, what is the wrap row count? log(n)
|
||||
// q: which diff hunk if any does this wrap row end?
|
||||
// q: for a given diff hunk, what is the wrap row count of the _other side_?
|
||||
|
||||
// struct DiffLineMapping {
|
||||
// group_boundaries: Vec<usize>, // group_boundaries[x] would be the start phys row for the `x`th group
|
||||
// // group_boundaries[x + 1] would be the end phsy ...
|
||||
// row_boundaries: Vec<usize>, // row_boundaries[x] would be the start wrapped row for the `x`th phys line
|
||||
// // row_boundaries[x + 1] would be the end wrapped_row ...
|
||||
// }
|
||||
|
||||
// group is either:
|
||||
// - a physical line that is not in a diff
|
||||
// - an entire diff
|
||||
//
|
||||
// we never split up a group with a spacer
|
||||
|
||||
// impl DiffLineMapping {
|
||||
// // modulo off-by-one errors
|
||||
// fn which_buffer_row_end(&self, wrap_row: usize) -> Option<usize> {
|
||||
// self.row_boundaries.binary_search(wrap_row).ok()
|
||||
// }
|
||||
|
||||
// fn number_of_spacers_needed(&self, physical_line: usize, other: &DiffLineMapping) -> isize {
|
||||
// (self.row_boundaries[physical_line + 1] - self.row_boundaries[physical_line]) - (other.row_boundaries[physical_line + 1] - other.row_boundaries[physical_line])
|
||||
// }
|
||||
|
||||
// // left[x].end - left[x.start] - (right[x].end - right[x].start)
|
||||
// }
|
||||
|
||||
// - we get some wrap row edits
|
||||
// - compute the affected range in the same way
|
||||
//
|
||||
// old:
|
||||
// loop {
|
||||
// find the next block in the affected region for the edit
|
||||
// insert an isomorphic transform leading up to that block
|
||||
// insert block
|
||||
// }
|
||||
//
|
||||
// new:
|
||||
// for each wrap row in the affected region {
|
||||
//
|
||||
// }
|
||||
|
||||
fn sync(&self, wrap_snapshot: &WrapSnapshot, mut edits: Patch<u32>) {
|
||||
let buffer = wrap_snapshot.buffer_snapshot();
|
||||
|
||||
|
||||
@@ -107,6 +107,8 @@ impl FoldPoint {
|
||||
}
|
||||
|
||||
pub fn to_offset(self, snapshot: &FoldSnapshot) -> FoldOffset {
|
||||
dbg!(&self);
|
||||
dbg!(snapshot.max_point());
|
||||
let (start, _, item) = snapshot
|
||||
.transforms
|
||||
.find::<Dimensions<FoldPoint, TransformSummary>, _>((), &self, Bias::Right);
|
||||
|
||||
@@ -590,6 +590,7 @@ impl InlayMap {
|
||||
.is_none_or(|edit| edit.old.start >= cursor.end().0)
|
||||
{
|
||||
let transform_start = new_transforms.summary().input.len;
|
||||
// FIXME: attempted to subtract with overflow
|
||||
let transform_end =
|
||||
buffer_edit.new.end + (cursor.end().0 - buffer_edit.old.end);
|
||||
push_isomorphic(
|
||||
|
||||
@@ -834,6 +834,25 @@ impl WrapSnapshot {
|
||||
None
|
||||
}
|
||||
|
||||
// Editor calls DisplayMap::sync()
|
||||
// - that calls all ther other WhateverMap::sync()s
|
||||
//
|
||||
// BlockMap::sync()
|
||||
// - WrapSnapshot
|
||||
// - GroupBoundary (for the other Editor's DisplayMap)
|
||||
// - the other Editor's BlockMap::sync() must have been called
|
||||
// - which requires this Editor's BlockMap::sync() to have been called
|
||||
//
|
||||
// MultiBuffer::sync() <- InlayMap::sync() <- ... <- WrapMap::sync() (us)
|
||||
// MultiBuffer::sync() <- InlayMap::sync() <- ... <- WrapMap::sync() (them)
|
||||
//
|
||||
// BlockMap::sync(our wrap map, their wrap map) (us)
|
||||
// BlockMap::sync(their wrap map, our wrap map) (them)
|
||||
|
||||
// pub fn next_group_boundary(&self, point: WrapPoint) -> Option<(u32, Option<(added_lines: u32, deleted_lines: u32)>)> {
|
||||
// // ...
|
||||
// }
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn text(&self) -> String {
|
||||
self.text_chunks(0).collect()
|
||||
|
||||
@@ -209,6 +209,27 @@ struct BufferState {
|
||||
_subscriptions: [gpui::Subscription; 2],
|
||||
}
|
||||
|
||||
// struct DiffModeQuery<T, const Mode: DiffMode>(T);
|
||||
|
||||
// struct InlaySnapshot {
|
||||
// multibuffer: EditorMultibufferSnapshot,
|
||||
// }
|
||||
|
||||
// struct EditorMultibuffer {
|
||||
// mode: DiffMode,
|
||||
// multibuffer: Entity<MultiBuffer>,
|
||||
// }
|
||||
|
||||
// trait ToPointGitAware {
|
||||
// fn to_point(&self, snapshot: ..., mode: DiffMode) -> Point;
|
||||
// }
|
||||
|
||||
// impl<T: ToPointGitAware> ToPoint for (T, DiffMode) {
|
||||
// fn to_point(&self, snapshot: ..., mode: DiffMode) -> (Point, DiffMode) {
|
||||
// self.0.to_point(snapshot, self.1)
|
||||
// }
|
||||
// }
|
||||
|
||||
struct DiffState {
|
||||
diff: Entity<BufferDiff>,
|
||||
_subscription: gpui::Subscription,
|
||||
@@ -265,6 +286,7 @@ enum DiffTransform {
|
||||
base_text_byte_range: Range<usize>,
|
||||
has_trailing_newline: bool,
|
||||
},
|
||||
SkippedHunk(TextSummary),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
@@ -486,6 +508,7 @@ impl<'a, D: TextDimension> Dimension<'a, DiffTransformSummary> for DiffTransform
|
||||
#[derive(Clone)]
|
||||
struct MultiBufferCursor<'a, D: TextDimension> {
|
||||
excerpts: Cursor<'a, 'static, Excerpt, ExcerptDimension<D>>,
|
||||
// DONE
|
||||
diff_transforms: Cursor<'a, 'static, DiffTransform, DiffTransforms<D>>,
|
||||
diffs: &'a TreeMap<BufferId, BufferDiffSnapshot>,
|
||||
cached_region: Option<MultiBufferRegion<'a, D>>,
|
||||
@@ -2461,6 +2484,7 @@ impl MultiBuffer {
|
||||
}
|
||||
|
||||
let mut excerpts = snapshot.excerpts.cursor::<ExcerptOffset>(());
|
||||
dbg!(snapshot.diff_transforms.iter().collect::<Vec<_>>());
|
||||
let mut old_diff_transforms = snapshot
|
||||
.diff_transforms
|
||||
.cursor::<Dimensions<ExcerptOffset, usize>>(());
|
||||
@@ -2471,6 +2495,7 @@ impl MultiBuffer {
|
||||
let mut at_transform_boundary = true;
|
||||
let mut end_of_current_insert = None;
|
||||
|
||||
dbg!("------------------", excerpt_edits.len());
|
||||
let mut excerpt_edits = excerpt_edits.into_iter().peekable();
|
||||
while let Some(edit) = excerpt_edits.next() {
|
||||
excerpts.seek_forward(&edit.new.start, Bias::Right);
|
||||
@@ -2510,10 +2535,17 @@ impl MultiBuffer {
|
||||
|
||||
// Compute the end of the edit in output coordinates.
|
||||
let edit_old_end_overshoot = edit.old.end - old_diff_transforms.start().0;
|
||||
let edit_new_end_overshoot = edit.new.end - new_diff_transforms.summary().excerpt_len();
|
||||
dbg!(new_diff_transforms.iter().collect::<Vec<_>>());
|
||||
// text between new_diff_transforms.summary().excerpt_len() and edit.new.end is
|
||||
// bone fide inserted, but it might be part of an added region.
|
||||
let edit_new_end_overshoot =
|
||||
dbg!(edit.new.end) - dbg!(new_diff_transforms.summary().excerpt_len());
|
||||
let edit_old_end = old_diff_transforms.start().1 + edit_old_end_overshoot.value;
|
||||
let edit_new_end =
|
||||
new_diff_transforms.summary().output.len + edit_new_end_overshoot.value;
|
||||
let mut edit_new_end = dbg!(new_diff_transforms.summary().output.len);
|
||||
if true && end_of_current_insert.is_none() {
|
||||
// FIXME
|
||||
edit_new_end += dbg!(edit_new_end_overshoot.value);
|
||||
}
|
||||
let output_edit = Edit {
|
||||
old: edit_old_start..edit_old_end,
|
||||
new: edit_new_start..edit_new_end,
|
||||
@@ -2532,6 +2564,7 @@ impl MultiBuffer {
|
||||
.peek()
|
||||
.is_none_or(|next_edit| next_edit.old.start >= old_diff_transforms.end().0)
|
||||
{
|
||||
dbg!("SHOULD BE HERE");
|
||||
let keep_next_old_transform = (old_diff_transforms.start().0 >= edit.old.end)
|
||||
&& match old_diff_transforms.item() {
|
||||
Some(DiffTransform::BufferContent {
|
||||
@@ -2579,7 +2612,17 @@ impl MultiBuffer {
|
||||
snapshot.diff_transforms = new_diff_transforms;
|
||||
snapshot.edit_count += 1;
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
// FIXME
|
||||
for edit in &output_edits {
|
||||
dbg!(edit.new.end, snapshot.len());
|
||||
assert!(
|
||||
edit.new.end <= snapshot.len(),
|
||||
"transforms: {:?}",
|
||||
snapshot.diff_transforms.iter().collect::<Vec<_>>()
|
||||
)
|
||||
}
|
||||
|
||||
// #[cfg(any(test, feature = "test-support"))]
|
||||
snapshot.check_invariants();
|
||||
output_edits
|
||||
}
|
||||
@@ -2672,7 +2715,7 @@ impl MultiBuffer {
|
||||
Self::push_buffer_content_transform(
|
||||
snapshot,
|
||||
new_diff_transforms,
|
||||
hunk_excerpt_start,
|
||||
dbg!(hunk_excerpt_start),
|
||||
*end_of_current_insert,
|
||||
);
|
||||
|
||||
@@ -2732,8 +2775,11 @@ impl MultiBuffer {
|
||||
}
|
||||
|
||||
if !hunk_buffer_range.is_empty() {
|
||||
dbg!("yep");
|
||||
*end_of_current_insert =
|
||||
Some((hunk_excerpt_end.min(excerpt_end), hunk_info));
|
||||
} else {
|
||||
dbg!("nope");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2801,8 +2847,10 @@ impl MultiBuffer {
|
||||
|
||||
for (end_offset, inserted_hunk_info) in inserted_region.into_iter().chain(unchanged_region)
|
||||
{
|
||||
dbg!(&inserted_hunk_info);
|
||||
let start_offset = new_transforms.summary().excerpt_len();
|
||||
if end_offset <= start_offset {
|
||||
dbg!();
|
||||
continue;
|
||||
}
|
||||
let summary_to_add = old_snapshot
|
||||
@@ -2813,13 +2861,15 @@ impl MultiBuffer {
|
||||
inserted_hunk_info,
|
||||
summary_to_add,
|
||||
) {
|
||||
new_transforms.push(
|
||||
DiffTransform::BufferContent {
|
||||
let transform = if inserted_hunk_info.is_some() {
|
||||
dbg!(DiffTransform::SkippedHunk(summary_to_add))
|
||||
} else {
|
||||
dbg!(DiffTransform::BufferContent {
|
||||
summary: summary_to_add,
|
||||
inserted_hunk_info,
|
||||
},
|
||||
(),
|
||||
)
|
||||
})
|
||||
};
|
||||
new_transforms.push(transform, ())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4091,6 +4141,7 @@ impl MultiBufferSnapshot {
|
||||
|
||||
summary
|
||||
}
|
||||
DiffTransform::SkippedHunk(_) => Default::default(),
|
||||
};
|
||||
if range.end < diff_transform_end {
|
||||
return result;
|
||||
@@ -4129,6 +4180,7 @@ impl MultiBufferSnapshot {
|
||||
}
|
||||
suffix
|
||||
}
|
||||
DiffTransform::SkippedHunk(_) => Default::default(),
|
||||
};
|
||||
|
||||
result.add_assign(&suffix);
|
||||
@@ -5769,15 +5821,16 @@ impl MultiBufferSnapshot {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
// #[cfg(any(test, feature = "test-support"))]
|
||||
impl MultiBufferSnapshot {
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn random_byte_range(&self, start_offset: usize, rng: &mut impl rand::Rng) -> Range<usize> {
|
||||
let end = self.clip_offset(rng.random_range(start_offset..=self.len()), Bias::Right);
|
||||
let start = self.clip_offset(rng.random_range(start_offset..=end), Bias::Right);
|
||||
start..end
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
// #[cfg(any(test, feature = "test-support"))]
|
||||
fn check_invariants(&self) {
|
||||
let excerpts = self.excerpts.items(());
|
||||
let excerpt_ids = self.excerpt_ids.items(());
|
||||
@@ -5838,10 +5891,46 @@ impl MultiBufferSnapshot {
|
||||
}
|
||||
}
|
||||
|
||||
fn next_non_skipped_diff_transform<'a, D: sum_tree::Dimension<'a, DiffTransformSummary>>(
|
||||
cursor: &mut Cursor<'a, 'static, DiffTransform, D>,
|
||||
) {
|
||||
cursor.next();
|
||||
if let Some(item) = cursor.item()
|
||||
&& item.is_skipped_hunk()
|
||||
{
|
||||
cursor.next();
|
||||
}
|
||||
// Can't have consecutive skipped hunks
|
||||
}
|
||||
|
||||
fn prev_non_skipped_diff_transform<'a, D: sum_tree::Dimension<'a, DiffTransformSummary>>(
|
||||
cursor: &mut Cursor<'a, 'static, DiffTransform, D>,
|
||||
) {
|
||||
cursor.prev();
|
||||
if let Some(item) = cursor.item()
|
||||
&& item.is_skipped_hunk()
|
||||
{
|
||||
cursor.prev();
|
||||
}
|
||||
// Can't have consecutive skipped hunks
|
||||
}
|
||||
|
||||
impl<'a, D> MultiBufferCursor<'a, D>
|
||||
where
|
||||
D: TextDimension + Ord + Sub<D, Output = D>,
|
||||
{
|
||||
// fn seek_forward_past_skipped_hunks(&mut self) {
|
||||
// while let Some(DiffTransform::SkippedHunk(_)) = self.diff_transforms.item() {
|
||||
// self.diff_transforms.next();
|
||||
// }
|
||||
// }
|
||||
|
||||
// fn seek_backward_past_skipped_hunks(&mut self) {
|
||||
// while let Some(DiffTransform::SkippedHunk(_)) = self.diff_transforms.item() {
|
||||
// self.diff_transforms.prev();
|
||||
// }
|
||||
// }
|
||||
|
||||
fn seek(&mut self, position: &D) {
|
||||
self.cached_region.take();
|
||||
self.diff_transforms
|
||||
@@ -5849,7 +5938,7 @@ where
|
||||
if self.diff_transforms.item().is_none()
|
||||
&& *position == self.diff_transforms.start().output_dimension.0
|
||||
{
|
||||
self.diff_transforms.prev();
|
||||
prev_non_skipped_diff_transform(&mut self.diff_transforms);
|
||||
}
|
||||
|
||||
let mut excerpt_position = self.diff_transforms.start().excerpt_dimension.0;
|
||||
@@ -5872,7 +5961,7 @@ where
|
||||
if self.diff_transforms.item().is_none()
|
||||
&& *position == self.diff_transforms.start().output_dimension.0
|
||||
{
|
||||
self.diff_transforms.prev();
|
||||
prev_non_skipped_diff_transform(&mut self.diff_transforms);
|
||||
}
|
||||
|
||||
let overshoot = *position - self.diff_transforms.start().output_dimension.0;
|
||||
@@ -5905,7 +5994,8 @@ where
|
||||
&& self.diff_transforms.start().excerpt_dimension < *self.excerpts.start()
|
||||
&& self.diff_transforms.next_item().is_some()
|
||||
{
|
||||
self.diff_transforms.next();
|
||||
// FIXME by the excerpt dimension comparison, there must be a non-skipped diff transform to find
|
||||
next_non_skipped_diff_transform(&mut self.diff_transforms);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5917,10 +6007,12 @@ where
|
||||
.excerpt_dimension
|
||||
.cmp(&self.excerpts.end())
|
||||
{
|
||||
cmp::Ordering::Less => self.diff_transforms.next(),
|
||||
cmp::Ordering::Less => {
|
||||
next_non_skipped_diff_transform(&mut self.diff_transforms);
|
||||
}
|
||||
cmp::Ordering::Greater => self.excerpts.next(),
|
||||
cmp::Ordering::Equal => {
|
||||
self.diff_transforms.next();
|
||||
next_non_skipped_diff_transform(&mut self.diff_transforms);
|
||||
if self.diff_transforms.end().excerpt_dimension > self.excerpts.end()
|
||||
|| self.diff_transforms.item().is_none()
|
||||
{
|
||||
@@ -5947,9 +6039,11 @@ where
|
||||
.cmp(self.excerpts.start())
|
||||
{
|
||||
cmp::Ordering::Less => self.excerpts.prev(),
|
||||
cmp::Ordering::Greater => self.diff_transforms.prev(),
|
||||
cmp::Ordering::Greater => {
|
||||
next_non_skipped_diff_transform(&mut self.diff_transforms);
|
||||
}
|
||||
cmp::Ordering::Equal => {
|
||||
self.diff_transforms.prev();
|
||||
prev_non_skipped_diff_transform(&mut self.diff_transforms);
|
||||
if self.diff_transforms.start().excerpt_dimension < *self.excerpts.start()
|
||||
|| self.diff_transforms.item().is_none()
|
||||
{
|
||||
@@ -5978,7 +6072,10 @@ where
|
||||
self.diff_transforms.next();
|
||||
|
||||
prev_transform.is_none_or(|next_transform| {
|
||||
matches!(next_transform, DiffTransform::BufferContent { .. })
|
||||
matches!(
|
||||
next_transform,
|
||||
DiffTransform::BufferContent { .. } | DiffTransform::SkippedHunk(_)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5993,7 +6090,7 @@ where
|
||||
|
||||
let next_transform = self.diff_transforms.next_item();
|
||||
next_transform.is_none_or(|next_transform| match next_transform {
|
||||
DiffTransform::BufferContent { .. } => true,
|
||||
DiffTransform::BufferContent { .. } | DiffTransform::SkippedHunk(_) => true,
|
||||
DiffTransform::DeletedHunk { hunk_info, .. } => self
|
||||
.excerpts
|
||||
.item()
|
||||
@@ -6090,6 +6187,10 @@ where
|
||||
range: start..end,
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
log::error!("cursor parked on skipped hunk");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6397,6 +6498,14 @@ impl DiffTransform {
|
||||
DiffTransform::BufferContent {
|
||||
inserted_hunk_info, ..
|
||||
} => *inserted_hunk_info,
|
||||
DiffTransform::SkippedHunk(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_skipped_hunk(&self) -> bool {
|
||||
match self {
|
||||
DiffTransform::SkippedHunk(_) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6405,6 +6514,10 @@ impl sum_tree::Item for DiffTransform {
|
||||
type Summary = DiffTransformSummary;
|
||||
|
||||
fn summary(&self, _: <Self::Summary as sum_tree::Summary>::Context<'_>) -> Self::Summary {
|
||||
// in "no deletions" mode,
|
||||
// DiffTransform::DeletedHunk doesn't add to output either
|
||||
// in "no additions" mode,
|
||||
// DiffTransform::BufferContent doesn't add to output if it's an insertion
|
||||
match self {
|
||||
DiffTransform::BufferContent { summary, .. } => DiffTransformSummary {
|
||||
input: *summary,
|
||||
@@ -6414,6 +6527,10 @@ impl sum_tree::Item for DiffTransform {
|
||||
input: TextSummary::default(),
|
||||
output: *summary,
|
||||
},
|
||||
DiffTransform::SkippedHunk(summary) => DiffTransformSummary {
|
||||
input: *summary,
|
||||
output: TextSummary::default(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6852,7 +6969,7 @@ impl<'a> Iterator for ReversedMultiBufferChunks<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// multi_buffer.chunks().map(|chunk| chunk.text()).collect::<String>() = "what the user sees"
|
||||
impl<'a> Iterator for MultiBufferChunks<'a> {
|
||||
type Item = Chunk<'a>;
|
||||
|
||||
@@ -6861,9 +6978,17 @@ impl<'a> Iterator for MultiBufferChunks<'a> {
|
||||
return None;
|
||||
}
|
||||
if self.range.start == self.diff_transforms.end().0 {
|
||||
self.diff_transforms.next();
|
||||
next_non_skipped_diff_transform(&mut self.diff_transforms);
|
||||
}
|
||||
|
||||
debug_assert!(self.range.start == self.diff_transforms.end().0);
|
||||
// self.diff_t.. |--------------|
|
||||
// self.range |-----------------------------|
|
||||
// |------| |-skipped hunk-| |-----------|
|
||||
// ^ ^
|
||||
|
||||
// figure out which transform we're going to operate on (it should be a non-skipped transform)
|
||||
dbg!(self.diff_transforms.item());
|
||||
let diff_transform_start = self.diff_transforms.start().0;
|
||||
let diff_transform_end = self.diff_transforms.end().0;
|
||||
debug_assert!(self.range.start < diff_transform_end);
|
||||
@@ -6892,7 +7017,7 @@ impl<'a> Iterator for MultiBufferChunks<'a> {
|
||||
chunk.text = after;
|
||||
chunk.chars = chunk.chars >> split_idx;
|
||||
chunk.tabs = chunk.tabs >> split_idx;
|
||||
|
||||
|
||||
Some(Chunk {
|
||||
text: before,
|
||||
chars,
|
||||
@@ -6946,6 +7071,7 @@ impl<'a> Iterator for MultiBufferChunks<'a> {
|
||||
};
|
||||
Some(chunk)
|
||||
}
|
||||
DiffTransform::SkippedHunk(_) => unreachable!("two skipped hunks in a row"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1377,6 +1377,45 @@ fn test_basic_diff_hunks(cx: &mut TestAppContext) {
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_insertion(cx: &mut TestAppContext) {
|
||||
let text = indoc!(
|
||||
"
|
||||
a
|
||||
b
|
||||
c
|
||||
"
|
||||
);
|
||||
let base_text = "";
|
||||
let buffer = cx.new(|cx| Buffer::local(text, cx));
|
||||
let diff = cx.new(|cx| BufferDiff::new_with_base_text(base_text, &buffer, cx));
|
||||
cx.run_until_parked();
|
||||
|
||||
let multibuffer = cx.new(|cx| {
|
||||
let mut multibuffer = MultiBuffer::singleton(buffer.clone(), cx);
|
||||
multibuffer.add_diff(diff.clone(), cx);
|
||||
multibuffer
|
||||
});
|
||||
|
||||
multibuffer.update(cx, |multibuffer, cx| {
|
||||
multibuffer.expand_diff_hunks(vec![Anchor::min()..Anchor::max()], cx);
|
||||
});
|
||||
cx.run_until_parked();
|
||||
let (mut snapshot, mut subscription) = multibuffer.update(cx, |multibuffer, cx| {
|
||||
(multibuffer.snapshot(cx), multibuffer.subscribe())
|
||||
});
|
||||
assert_eq!(
|
||||
snapshot.text(),
|
||||
indoc!(
|
||||
"
|
||||
a
|
||||
b
|
||||
c
|
||||
"
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn test_repeatedly_expand_a_diff_hunk(cx: &mut TestAppContext) {
|
||||
let text = indoc!(
|
||||
@@ -2328,18 +2367,18 @@ impl ReferenceMultibuffer {
|
||||
}
|
||||
|
||||
// Add the inserted text for the hunk.
|
||||
if hunk_range.end > offset {
|
||||
let len = text.len();
|
||||
text.extend(buffer.text_for_range(offset..hunk_range.end));
|
||||
regions.push(ReferenceRegion {
|
||||
buffer_id: Some(buffer.remote_id()),
|
||||
range: len..text.len(),
|
||||
buffer_start: Some(buffer.offset_to_point(offset)),
|
||||
status: Some(DiffHunkStatus::added(hunk.secondary_status)),
|
||||
excerpt_id: Some(excerpt.id),
|
||||
});
|
||||
offset = hunk_range.end;
|
||||
}
|
||||
// if hunk_range.end > offset {
|
||||
// let len = text.len();
|
||||
// text.extend(buffer.text_for_range(offset..hunk_range.end));
|
||||
// regions.push(ReferenceRegion {
|
||||
// buffer_id: Some(buffer.remote_id()),
|
||||
// range: len..text.len(),
|
||||
// buffer_start: Some(buffer.offset_to_point(offset)),
|
||||
// status: Some(DiffHunkStatus::added(hunk.secondary_status)),
|
||||
// excerpt_id: Some(excerpt.id),
|
||||
// });
|
||||
// offset = hunk_range.end;
|
||||
// }
|
||||
}
|
||||
|
||||
// Add the buffer text for the rest of the excerpt.
|
||||
@@ -3962,3 +4001,28 @@ fn test_random_chunk_bitmaps_with_diffs(cx: &mut App, mut rng: StdRng) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_seeking_with_skipped_hunks() {
|
||||
let first_part = "one\n";
|
||||
let transforms = SumTree::from_iter(
|
||||
[
|
||||
DiffTransform::BufferContent {
|
||||
summary: TextSummary::from(first_part),
|
||||
inserted_hunk_info: None,
|
||||
},
|
||||
DiffTransform::SkippedHunk(TextSummary::from("2\n")),
|
||||
DiffTransform::SkippedHunk(TextSummary::from("22\n")),
|
||||
DiffTransform::BufferContent {
|
||||
summary: TextSummary::from("3!!!\n"),
|
||||
inserted_hunk_info: None,
|
||||
},
|
||||
],
|
||||
(),
|
||||
);
|
||||
let mut cursor = transforms.cursor::<usize>(());
|
||||
cursor.seek(&first_part.len(), Bias::Left);
|
||||
dbg!(cursor.item());
|
||||
cursor.seek(&first_part.len(), Bias::Right);
|
||||
dbg!(cursor.item());
|
||||
}
|
||||
|
||||
@@ -169,6 +169,16 @@ impl ConflictSet {
|
||||
cx.emit(update);
|
||||
}
|
||||
|
||||
// Vec<(Range<usize>)>
|
||||
// Vec<(Range<usize>, &str)>
|
||||
//
|
||||
// [(1..2, ""), (6..7, "")]
|
||||
// {"hello": "world"}
|
||||
// {hello: "world"}
|
||||
//
|
||||
// foo(bar);
|
||||
// }
|
||||
|
||||
pub fn parse(buffer: &text::BufferSnapshot) -> ConflictSetSnapshot {
|
||||
let mut conflicts = Vec::new();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user