multi_buffer: Optimize a bunch of things (#48519)
Release Notes: - N/A *or* Added/Fixed/Improved ... --------- Co-authored-by: Cole Miller <cole@zed.dev>
This commit is contained in:
1 parent
7dcff21dc9
commit
74746aa974
12 files changed
+256
-157
No files matched your search
@@ -320,7 +320,7 @@ mod tests {
|
||||
);
|
||||
let snapshot = buffer.snapshot();
|
||||
|
||||
let mut finder = StreamingFuzzyMatcher::new(snapshot);
|
||||
let mut finder = StreamingFuzzyMatcher::new(snapshot.clone());
|
||||
assert_eq!(push(&mut finder, ""), None);
|
||||
assert_eq!(finish(finder), None);
|
||||
}
|
||||
@@ -334,7 +334,7 @@ mod tests {
|
||||
);
|
||||
let snapshot = buffer.snapshot();
|
||||
|
||||
let mut finder = StreamingFuzzyMatcher::new(snapshot);
|
||||
let mut finder = StreamingFuzzyMatcher::new(snapshot.clone());
|
||||
|
||||
// Push partial query
|
||||
assert_eq!(push(&mut finder, "This"), None);
|
||||
@@ -366,7 +366,7 @@ mod tests {
|
||||
);
|
||||
let snapshot = buffer.snapshot();
|
||||
|
||||
let mut finder = StreamingFuzzyMatcher::new(snapshot);
|
||||
let mut finder = StreamingFuzzyMatcher::new(snapshot.clone());
|
||||
|
||||
// Push a fuzzy query that should match the first function
|
||||
assert_eq!(
|
||||
@@ -392,7 +392,7 @@ mod tests {
|
||||
);
|
||||
let snapshot = buffer.snapshot();
|
||||
|
||||
let mut finder = StreamingFuzzyMatcher::new(snapshot);
|
||||
let mut finder = StreamingFuzzyMatcher::new(snapshot.clone());
|
||||
|
||||
// No match initially
|
||||
assert_eq!(push(&mut finder, "Lin"), None);
|
||||
@@ -421,7 +421,7 @@ mod tests {
|
||||
);
|
||||
let snapshot = buffer.snapshot();
|
||||
|
||||
let mut finder = StreamingFuzzyMatcher::new(snapshot);
|
||||
let mut finder = StreamingFuzzyMatcher::new(snapshot.clone());
|
||||
|
||||
// Push text in small chunks across line boundaries
|
||||
assert_eq!(push(&mut finder, "jumps "), None); // No newline yet
|
||||
@@ -459,7 +459,7 @@ mod tests {
|
||||
);
|
||||
let snapshot = buffer.snapshot();
|
||||
|
||||
let mut finder = StreamingFuzzyMatcher::new(snapshot);
|
||||
let mut finder = StreamingFuzzyMatcher::new(snapshot.clone());
|
||||
|
||||
assert_eq!(
|
||||
push(&mut finder, "impl Debug for User {\n"),
|
||||
@@ -716,7 +716,7 @@ mod tests {
|
||||
"Expected to match `second_function` based on the line hint"
|
||||
);
|
||||
|
||||
let mut matcher = StreamingFuzzyMatcher::new(snapshot);
|
||||
let mut matcher = StreamingFuzzyMatcher::new(snapshot.clone());
|
||||
matcher.push(query, None);
|
||||
matcher.finish();
|
||||
let best_match = matcher.select_best_match();
|
||||
@@ -732,7 +732,7 @@ mod tests {
|
||||
let buffer = TextBuffer::new(ReplicaId::LOCAL, BufferId::new(1).unwrap(), text.clone());
|
||||
let snapshot = buffer.snapshot();
|
||||
|
||||
let mut matcher = StreamingFuzzyMatcher::new(snapshot);
|
||||
let mut matcher = StreamingFuzzyMatcher::new(snapshot.clone());
|
||||
|
||||
// Split query into random chunks
|
||||
let chunks = to_random_chunks(rng, query);
|
||||
|
||||
@@ -30,7 +30,7 @@ pub struct BufferDiff {
|
||||
#[derive(Clone)]
|
||||
pub struct BufferDiffSnapshot {
|
||||
inner: BufferDiffInner<language::BufferSnapshot>,
|
||||
secondary_diff: Option<Box<BufferDiffSnapshot>>,
|
||||
secondary_diff: Option<Arc<BufferDiffSnapshot>>,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for BufferDiffSnapshot {
|
||||
@@ -222,11 +222,11 @@ impl std::fmt::Debug for BufferDiffInner<language::BufferSnapshot> {
|
||||
impl BufferDiffSnapshot {
|
||||
#[cfg(test)]
|
||||
fn new_sync(
|
||||
buffer: text::BufferSnapshot,
|
||||
buffer: &text::BufferSnapshot,
|
||||
diff_base: String,
|
||||
cx: &mut gpui::TestAppContext,
|
||||
) -> BufferDiffSnapshot {
|
||||
let buffer_diff = cx.new(|cx| BufferDiff::new_with_base_text(&diff_base, &buffer, cx));
|
||||
let buffer_diff = cx.new(|cx| BufferDiff::new_with_base_text(&diff_base, buffer, cx));
|
||||
buffer_diff.update(cx, |buffer_diff, cx| buffer_diff.snapshot(cx))
|
||||
}
|
||||
|
||||
@@ -950,10 +950,10 @@ fn build_diff_options(
|
||||
|
||||
fn compute_hunks(
|
||||
diff_base: Option<(Arc<str>, Rope)>,
|
||||
buffer: text::BufferSnapshot,
|
||||
buffer: &text::BufferSnapshot,
|
||||
diff_options: Option<DiffOptions>,
|
||||
) -> SumTree<InternalDiffHunk> {
|
||||
let mut tree = SumTree::new(&buffer);
|
||||
let mut tree = SumTree::new(buffer);
|
||||
|
||||
if let Some((diff_base, diff_base_rope)) = diff_base {
|
||||
let buffer_text = buffer.as_rope().to_string();
|
||||
@@ -980,7 +980,7 @@ fn compute_hunks(
|
||||
base_word_diffs: Vec::default(),
|
||||
buffer_word_diffs: Vec::default(),
|
||||
},
|
||||
&buffer,
|
||||
buffer,
|
||||
);
|
||||
return tree;
|
||||
}
|
||||
@@ -992,11 +992,11 @@ fn compute_hunks(
|
||||
&patch,
|
||||
hunk_index,
|
||||
&diff_base_rope,
|
||||
&buffer,
|
||||
buffer,
|
||||
&mut divergence,
|
||||
diff_options.as_ref(),
|
||||
);
|
||||
tree.push(hunk, &buffer);
|
||||
tree.push(hunk, buffer);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1007,7 +1007,7 @@ fn compute_hunks(
|
||||
base_word_diffs: Vec::default(),
|
||||
buffer_word_diffs: Vec::default(),
|
||||
},
|
||||
&buffer,
|
||||
buffer,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1544,7 +1544,7 @@ impl BufferDiff {
|
||||
base_text
|
||||
.clone()
|
||||
.map(|base_text| (base_text, base_text_rope.clone())),
|
||||
buffer.clone(),
|
||||
&buffer,
|
||||
diff_options,
|
||||
);
|
||||
let base_text = base_text.unwrap_or_default();
|
||||
@@ -1785,10 +1785,10 @@ impl BufferDiff {
|
||||
base_text_exists: self.inner.base_text_exists,
|
||||
buffer_snapshot: self.inner.buffer_snapshot.clone(),
|
||||
},
|
||||
secondary_diff: self
|
||||
.secondary_diff
|
||||
.as_ref()
|
||||
.map(|diff| Box::new(diff.read(cx).snapshot(cx))),
|
||||
secondary_diff: self.secondary_diff.as_ref().map(|diff| {
|
||||
debug_assert!(diff.read(cx).secondary_diff.is_none());
|
||||
Arc::new(diff.read(cx).snapshot(cx))
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2018,7 +2018,7 @@ mod tests {
|
||||
.unindent();
|
||||
|
||||
let mut buffer = Buffer::new(ReplicaId::LOCAL, BufferId::new(1).unwrap(), buffer_text);
|
||||
let mut diff = BufferDiffSnapshot::new_sync(buffer.clone(), diff_base.clone(), cx);
|
||||
let mut diff = BufferDiffSnapshot::new_sync(&buffer, diff_base.clone(), cx);
|
||||
assert_hunks(
|
||||
diff.hunks_intersecting_range(
|
||||
Anchor::min_max_range_for_buffer(buffer.remote_id()),
|
||||
@@ -2030,7 +2030,7 @@ mod tests {
|
||||
);
|
||||
|
||||
buffer.edit([(0..0, "point five\n")]);
|
||||
diff = BufferDiffSnapshot::new_sync(buffer.clone(), diff_base.clone(), cx);
|
||||
diff = BufferDiffSnapshot::new_sync(&buffer, diff_base.clone(), cx);
|
||||
assert_hunks(
|
||||
diff.hunks_intersecting_range(
|
||||
Anchor::min_max_range_for_buffer(buffer.remote_id()),
|
||||
@@ -2101,10 +2101,9 @@ mod tests {
|
||||
.unindent();
|
||||
|
||||
let buffer = Buffer::new(ReplicaId::LOCAL, BufferId::new(1).unwrap(), buffer_text);
|
||||
let unstaged_diff = BufferDiffSnapshot::new_sync(buffer.clone(), index_text, cx);
|
||||
let mut uncommitted_diff =
|
||||
BufferDiffSnapshot::new_sync(buffer.clone(), head_text.clone(), cx);
|
||||
uncommitted_diff.secondary_diff = Some(Box::new(unstaged_diff));
|
||||
let unstaged_diff = BufferDiffSnapshot::new_sync(&buffer, index_text, cx);
|
||||
let mut uncommitted_diff = BufferDiffSnapshot::new_sync(&buffer, head_text.clone(), cx);
|
||||
uncommitted_diff.secondary_diff = Some(Arc::new(unstaged_diff));
|
||||
|
||||
let expected_hunks = vec![
|
||||
(2..3, "two\n", "TWO\n", DiffHunkStatus::modified_none()),
|
||||
@@ -2631,7 +2630,7 @@ mod tests {
|
||||
let mut buffer = Buffer::new(ReplicaId::LOCAL, BufferId::new(1).unwrap(), buffer_text_1);
|
||||
|
||||
let empty_diff = cx.update(|cx| BufferDiff::new(&buffer, cx).snapshot(cx));
|
||||
let diff_1 = BufferDiffSnapshot::new_sync(buffer.clone(), base_text.clone(), cx);
|
||||
let diff_1 = BufferDiffSnapshot::new_sync(&buffer, base_text.clone(), cx);
|
||||
let DiffChanged {
|
||||
changed_range,
|
||||
base_text_changed_range,
|
||||
@@ -2666,7 +2665,7 @@ mod tests {
|
||||
"
|
||||
.unindent(),
|
||||
);
|
||||
let diff_2 = BufferDiffSnapshot::new_sync(buffer.clone(), base_text.clone(), cx);
|
||||
let diff_2 = BufferDiffSnapshot::new_sync(&buffer, base_text.clone(), cx);
|
||||
let DiffChanged {
|
||||
changed_range,
|
||||
base_text_changed_range,
|
||||
@@ -2704,7 +2703,7 @@ mod tests {
|
||||
"
|
||||
.unindent(),
|
||||
);
|
||||
let diff_3 = BufferDiffSnapshot::new_sync(buffer.clone(), base_text.clone(), cx);
|
||||
let diff_3 = BufferDiffSnapshot::new_sync(&buffer, base_text.clone(), cx);
|
||||
let DiffChanged {
|
||||
changed_range,
|
||||
base_text_changed_range,
|
||||
@@ -2738,7 +2737,7 @@ mod tests {
|
||||
"
|
||||
.unindent(),
|
||||
);
|
||||
let diff_4 = BufferDiffSnapshot::new_sync(buffer.clone(), base_text.clone(), cx);
|
||||
let diff_4 = BufferDiffSnapshot::new_sync(&buffer, base_text.clone(), cx);
|
||||
let DiffChanged {
|
||||
changed_range,
|
||||
base_text_changed_range,
|
||||
@@ -3172,11 +3171,11 @@ mod tests {
|
||||
.unindent();
|
||||
|
||||
let mut buffer = Buffer::new(ReplicaId::LOCAL, BufferId::new(1).unwrap(), buffer_text);
|
||||
let old_buffer = buffer.snapshot();
|
||||
let diff_a = BufferDiffSnapshot::new_sync(buffer.clone(), base_text.clone(), cx);
|
||||
let old_buffer = buffer.snapshot().clone();
|
||||
let diff_a = BufferDiffSnapshot::new_sync(&buffer, base_text.clone(), cx);
|
||||
|
||||
buffer.edit([(Point::new(1, 3)..Point::new(1, 3), "\n")]);
|
||||
let diff_b = BufferDiffSnapshot::new_sync(buffer.clone(), base_text, cx);
|
||||
let diff_b = BufferDiffSnapshot::new_sync(&buffer, base_text, cx);
|
||||
|
||||
let DiffChanged {
|
||||
changed_range,
|
||||
@@ -3235,11 +3234,11 @@ mod tests {
|
||||
.unindent();
|
||||
|
||||
let mut buffer_2 = Buffer::new(ReplicaId::LOCAL, BufferId::new(2).unwrap(), buffer_text_2);
|
||||
let old_buffer_2 = buffer_2.snapshot();
|
||||
let diff_2a = BufferDiffSnapshot::new_sync(buffer_2.clone(), base_text_2.clone(), cx);
|
||||
let old_buffer_2 = buffer_2.snapshot().clone();
|
||||
let diff_2a = BufferDiffSnapshot::new_sync(&buffer_2, base_text_2.clone(), cx);
|
||||
|
||||
buffer_2.edit([(Point::new(4, 0)..Point::new(4, 4), "FIVE_CHANGED")]);
|
||||
let diff_2b = BufferDiffSnapshot::new_sync(buffer_2.clone(), base_text_2, cx);
|
||||
let diff_2b = BufferDiffSnapshot::new_sync(&buffer_2, base_text_2, cx);
|
||||
|
||||
let DiffChanged {
|
||||
changed_range,
|
||||
@@ -3293,7 +3292,7 @@ mod tests {
|
||||
buffer_text_1.to_string(),
|
||||
);
|
||||
|
||||
let old_base_snapshot_1 = base_text_buffer.snapshot();
|
||||
let old_base_snapshot_1 = base_text_buffer.snapshot().clone();
|
||||
let old_hunks_1 = compute_hunks(
|
||||
Some((Arc::from(initial_base), Rope::from(initial_base))),
|
||||
buffer.snapshot(),
|
||||
@@ -3352,7 +3351,7 @@ mod tests {
|
||||
buffer_text_2.to_string(),
|
||||
);
|
||||
|
||||
let old_base_snapshot_2 = base_buf_2.snapshot();
|
||||
let old_base_snapshot_2 = base_buf_2.snapshot().clone();
|
||||
let old_hunks_2 = compute_hunks(
|
||||
Some((Arc::from(simple_base), Rope::from(simple_base))),
|
||||
buffer_2.snapshot(),
|
||||
@@ -3419,7 +3418,7 @@ mod tests {
|
||||
buffer_text_3.to_string(),
|
||||
);
|
||||
|
||||
let old_base_snapshot_3 = base_buf_3.snapshot();
|
||||
let old_base_snapshot_3 = base_buf_3.snapshot().clone();
|
||||
let old_hunks_3 = compute_hunks(
|
||||
Some((Arc::from(base_3), Rope::from(base_3))),
|
||||
buffer_3.snapshot(),
|
||||
@@ -3485,8 +3484,8 @@ mod tests {
|
||||
buffer_text_4.to_string(),
|
||||
);
|
||||
|
||||
let old_base_snapshot_4 = base_buf_4.snapshot();
|
||||
let old_buffer_snapshot_4 = buffer_4.snapshot();
|
||||
let old_base_snapshot_4 = base_buf_4.snapshot().clone();
|
||||
let old_buffer_snapshot_4 = buffer_4.snapshot().clone();
|
||||
let old_hunks_4 = compute_hunks(
|
||||
Some((Arc::from(base_4), Rope::from(base_4))),
|
||||
buffer_4.snapshot(),
|
||||
|
||||
@@ -441,6 +441,15 @@ impl DisplayMap {
|
||||
return;
|
||||
};
|
||||
|
||||
// Second call to set_companion doesn't need to do anything
|
||||
if companion_display_map
|
||||
.update(cx, |companion_dm, _| companion_dm.companion.is_none())
|
||||
.unwrap_or(true)
|
||||
{
|
||||
self.companion = Some((companion_display_map, companion));
|
||||
return;
|
||||
}
|
||||
|
||||
let rhs_display_map_id = companion.read(cx).rhs_display_map_id;
|
||||
if self.entity_id != rhs_display_map_id {
|
||||
let buffer_mapping = companion
|
||||
|
||||
@@ -1110,20 +1110,32 @@ impl BlockMap {
|
||||
let mut companion_tab_point_cursor = companion_snapshot.tab_point_cursor();
|
||||
let mut companion_wrap_point_cursor = companion_snapshot.wrap_point_cursor();
|
||||
|
||||
let mut determine_spacer = |our_point: Point, their_point: Point, delta: i32| {
|
||||
let our_wrap = our_wrap_point_cursor
|
||||
let mut our_wrapper = |our_point: Point| {
|
||||
our_wrap_point_cursor
|
||||
.map(our_tab_point_cursor.map(
|
||||
our_fold_point_cursor.map(our_inlay_point_cursor.map(our_point), Bias::Left),
|
||||
))
|
||||
.row();
|
||||
let companion_wrap = companion_wrap_point_cursor
|
||||
.row()
|
||||
};
|
||||
let mut companion_wrapper = |their_point: Point| {
|
||||
companion_wrap_point_cursor
|
||||
.map(
|
||||
companion_tab_point_cursor.map(
|
||||
companion_fold_point_cursor
|
||||
.map(companion_inlay_point_cursor.map(their_point), Bias::Left),
|
||||
),
|
||||
)
|
||||
.row();
|
||||
.row()
|
||||
};
|
||||
fn determine_spacer(
|
||||
our_wrapper: &mut impl FnMut(Point) -> WrapRow,
|
||||
companion_wrapper: &mut impl FnMut(Point) -> WrapRow,
|
||||
our_point: Point,
|
||||
their_point: Point,
|
||||
delta: i32,
|
||||
) -> (i32, Option<(WrapRow, u32)>) {
|
||||
let our_wrap = our_wrapper(our_point);
|
||||
let companion_wrap = companion_wrapper(their_point);
|
||||
let new_delta = companion_wrap.0 as i32 - our_wrap.0 as i32;
|
||||
|
||||
let spacer = if new_delta > delta {
|
||||
@@ -1133,7 +1145,7 @@ impl BlockMap {
|
||||
None
|
||||
};
|
||||
(new_delta, spacer)
|
||||
};
|
||||
}
|
||||
|
||||
let mut result = Vec::new();
|
||||
|
||||
@@ -1179,12 +1191,8 @@ impl BlockMap {
|
||||
// Case 3: We are at the start of the excerpt--no previous row to use as the baseline.
|
||||
(first_point, edit_for_first_point.new.start)
|
||||
};
|
||||
let our_baseline = wrap_snapshot
|
||||
.make_wrap_point(our_baseline, Bias::Left)
|
||||
.row();
|
||||
let their_baseline = companion_snapshot
|
||||
.make_wrap_point(their_baseline, Bias::Left)
|
||||
.row();
|
||||
let our_baseline = our_wrapper(our_baseline);
|
||||
let their_baseline = companion_wrapper(their_baseline);
|
||||
|
||||
let mut delta = their_baseline.0 as i32 - our_baseline.0 as i32;
|
||||
|
||||
@@ -1201,8 +1209,13 @@ impl BlockMap {
|
||||
current_boundary = next_point;
|
||||
}
|
||||
|
||||
let (new_delta, spacer) =
|
||||
determine_spacer(current_boundary, current_range.end, delta);
|
||||
let (new_delta, spacer) = determine_spacer(
|
||||
&mut our_wrapper,
|
||||
&mut companion_wrapper,
|
||||
current_boundary,
|
||||
current_range.end,
|
||||
delta,
|
||||
);
|
||||
|
||||
delta = new_delta;
|
||||
if let Some((wrap_row, height)) = spacer {
|
||||
@@ -1229,8 +1242,13 @@ impl BlockMap {
|
||||
}
|
||||
|
||||
// Align the two sides at the start of this group.
|
||||
let (delta_at_start, mut spacer_at_start) =
|
||||
determine_spacer(current_boundary, current_range.start, delta);
|
||||
let (delta_at_start, mut spacer_at_start) = determine_spacer(
|
||||
&mut our_wrapper,
|
||||
&mut companion_wrapper,
|
||||
current_boundary,
|
||||
current_range.start,
|
||||
delta,
|
||||
);
|
||||
delta = delta_at_start;
|
||||
|
||||
while let Some(next_point) = source_points.peek().copied() {
|
||||
@@ -1260,8 +1278,13 @@ impl BlockMap {
|
||||
break;
|
||||
}
|
||||
|
||||
let (delta_at_end, spacer_at_end) =
|
||||
determine_spacer(current_boundary, current_range.end, delta);
|
||||
let (delta_at_end, spacer_at_end) = determine_spacer(
|
||||
&mut our_wrapper,
|
||||
&mut companion_wrapper,
|
||||
current_boundary,
|
||||
current_range.end,
|
||||
delta,
|
||||
);
|
||||
delta = delta_at_end;
|
||||
|
||||
if let Some((wrap_row, mut height)) = spacer_at_start {
|
||||
@@ -1289,8 +1312,13 @@ impl BlockMap {
|
||||
}
|
||||
|
||||
if last_source_point == excerpt.source_excerpt_range.end {
|
||||
let (_new_delta, spacer) =
|
||||
determine_spacer(last_source_point, excerpt.target_excerpt_range.end, delta);
|
||||
let (_new_delta, spacer) = determine_spacer(
|
||||
&mut our_wrapper,
|
||||
&mut companion_wrapper,
|
||||
last_source_point,
|
||||
excerpt.target_excerpt_range.end,
|
||||
delta,
|
||||
);
|
||||
if let Some((wrap_row, height)) = spacer {
|
||||
result.push((
|
||||
BlockPlacement::Below(wrap_row),
|
||||
|
||||
@@ -523,6 +523,7 @@ impl SplittableEditor {
|
||||
convert_lhs_rows_to_rhs,
|
||||
);
|
||||
|
||||
// stream this
|
||||
for (path, diff) in path_diffs {
|
||||
for (lhs, rhs) in
|
||||
lhs.update_path_excerpts_from_rhs(path, &self.rhs_multibuffer, diff.clone(), cx)
|
||||
|
||||
@@ -151,16 +151,16 @@ pub struct TreeSitterData {
|
||||
const MAX_ROWS_IN_A_CHUNK: u32 = 50;
|
||||
|
||||
impl TreeSitterData {
|
||||
fn clear(&mut self, snapshot: text::BufferSnapshot) {
|
||||
self.chunks = RowChunks::new(snapshot, MAX_ROWS_IN_A_CHUNK);
|
||||
fn clear(&mut self, snapshot: &text::BufferSnapshot) {
|
||||
self.chunks = RowChunks::new(&snapshot, MAX_ROWS_IN_A_CHUNK);
|
||||
self.brackets_by_chunks.get_mut().clear();
|
||||
self.brackets_by_chunks
|
||||
.get_mut()
|
||||
.resize(self.chunks.len(), None);
|
||||
}
|
||||
|
||||
fn new(snapshot: text::BufferSnapshot) -> Self {
|
||||
let chunks = RowChunks::new(snapshot, MAX_ROWS_IN_A_CHUNK);
|
||||
fn new(snapshot: &text::BufferSnapshot) -> Self {
|
||||
let chunks = RowChunks::new(&snapshot, MAX_ROWS_IN_A_CHUNK);
|
||||
Self {
|
||||
brackets_by_chunks: Mutex::new(vec![None; chunks.len()]),
|
||||
chunks,
|
||||
@@ -188,12 +188,12 @@ struct BufferBranchState {
|
||||
pub struct BufferSnapshot {
|
||||
pub text: text::BufferSnapshot,
|
||||
pub syntax: SyntaxSnapshot,
|
||||
file: Option<Arc<dyn File>>,
|
||||
tree_sitter_data: Arc<TreeSitterData>,
|
||||
diagnostics: TreeMap<LanguageServerId, DiagnosticSet>,
|
||||
remote_selections: TreeMap<ReplicaId, SelectionSet>,
|
||||
language: Option<Arc<Language>>,
|
||||
file: Option<Arc<dyn File>>,
|
||||
non_text_state_update_count: usize,
|
||||
tree_sitter_data: Arc<TreeSitterData>,
|
||||
pub capability: Capability,
|
||||
}
|
||||
|
||||
@@ -1168,14 +1168,14 @@ impl Buffer {
|
||||
let buffer_id = entity_id.as_non_zero_u64().into();
|
||||
async move {
|
||||
let text =
|
||||
TextBuffer::new_normalized(ReplicaId::LOCAL, buffer_id, Default::default(), text)
|
||||
.snapshot();
|
||||
TextBuffer::new_normalized(ReplicaId::LOCAL, buffer_id, Default::default(), text);
|
||||
let text = text.into_snapshot();
|
||||
let mut syntax = SyntaxMap::new(&text).snapshot();
|
||||
if let Some(language) = language.clone() {
|
||||
let language_registry = language_registry.clone();
|
||||
syntax.reparse(&text, language_registry, language);
|
||||
}
|
||||
let tree_sitter_data = TreeSitterData::new(text.clone());
|
||||
let tree_sitter_data = TreeSitterData::new(&text);
|
||||
BufferSnapshot {
|
||||
text,
|
||||
syntax,
|
||||
@@ -1198,10 +1198,10 @@ impl Buffer {
|
||||
buffer_id,
|
||||
Default::default(),
|
||||
Rope::new(),
|
||||
)
|
||||
.snapshot();
|
||||
);
|
||||
let text = text.into_snapshot();
|
||||
let syntax = SyntaxMap::new(&text).snapshot();
|
||||
let tree_sitter_data = TreeSitterData::new(text.clone());
|
||||
let tree_sitter_data = TreeSitterData::new(&text);
|
||||
BufferSnapshot {
|
||||
text,
|
||||
syntax,
|
||||
@@ -1226,12 +1226,12 @@ impl Buffer {
|
||||
let buffer_id = entity_id.as_non_zero_u64().into();
|
||||
let text =
|
||||
TextBuffer::new_normalized(ReplicaId::LOCAL, buffer_id, Default::default(), text)
|
||||
.snapshot();
|
||||
.into_snapshot();
|
||||
let mut syntax = SyntaxMap::new(&text).snapshot();
|
||||
if let Some(language) = language.clone() {
|
||||
syntax.reparse(&text, language_registry, language);
|
||||
}
|
||||
let tree_sitter_data = TreeSitterData::new(text.clone());
|
||||
let tree_sitter_data = TreeSitterData::new(&text);
|
||||
BufferSnapshot {
|
||||
text,
|
||||
syntax,
|
||||
@@ -1249,18 +1249,21 @@ impl Buffer {
|
||||
/// cheap, and allows reading from the buffer on a background thread.
|
||||
pub fn snapshot(&self) -> BufferSnapshot {
|
||||
let text = self.text.snapshot();
|
||||
let mut syntax_map = self.syntax_map.lock();
|
||||
syntax_map.interpolate(&text);
|
||||
let syntax = syntax_map.snapshot();
|
||||
|
||||
let syntax = {
|
||||
let mut syntax_map = self.syntax_map.lock();
|
||||
syntax_map.interpolate(text);
|
||||
syntax_map.snapshot()
|
||||
};
|
||||
|
||||
let tree_sitter_data = if self.text.version() != *self.tree_sitter_data.version() {
|
||||
Arc::new(TreeSitterData::new(text.clone()))
|
||||
Arc::new(TreeSitterData::new(text))
|
||||
} else {
|
||||
self.tree_sitter_data.clone()
|
||||
};
|
||||
|
||||
BufferSnapshot {
|
||||
text,
|
||||
text: text.clone(),
|
||||
syntax,
|
||||
tree_sitter_data,
|
||||
file: self.file.clone(),
|
||||
@@ -1304,7 +1307,7 @@ impl Buffer {
|
||||
) -> Task<EditPreview> {
|
||||
let registry = self.language_registry();
|
||||
let language = self.language().cloned();
|
||||
let old_snapshot = self.text.snapshot();
|
||||
let old_snapshot = self.text.snapshot().clone();
|
||||
let mut branch_buffer = self.text.branch();
|
||||
let mut syntax_snapshot = self.syntax_map.lock().snapshot();
|
||||
cx.background_spawn(async move {
|
||||
@@ -1323,7 +1326,7 @@ impl Buffer {
|
||||
}
|
||||
EditPreview {
|
||||
old_snapshot,
|
||||
applied_edits_snapshot: branch_buffer.snapshot(),
|
||||
applied_edits_snapshot: branch_buffer.into_snapshot(),
|
||||
syntax_snapshot,
|
||||
}
|
||||
})
|
||||
@@ -1416,8 +1419,7 @@ impl Buffer {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) fn as_text_snapshot(&self) -> &text::BufferSnapshot {
|
||||
pub fn as_text_snapshot(&self) -> &text::BufferSnapshot {
|
||||
&self.text
|
||||
}
|
||||
|
||||
@@ -1425,7 +1427,8 @@ impl Buffer {
|
||||
/// language-related state like the syntax tree or diagnostics.
|
||||
#[ztracing::instrument(skip_all)]
|
||||
pub fn text_snapshot(&self) -> text::BufferSnapshot {
|
||||
self.text.snapshot()
|
||||
// todo lw
|
||||
self.text.snapshot().clone()
|
||||
}
|
||||
|
||||
/// The file associated with the buffer, if any.
|
||||
@@ -1781,12 +1784,15 @@ impl Buffer {
|
||||
self.sync_parse_timeout = timeout;
|
||||
}
|
||||
|
||||
fn invalidate_tree_sitter_data(&mut self, snapshot: text::BufferSnapshot) {
|
||||
match Arc::get_mut(&mut self.tree_sitter_data) {
|
||||
fn invalidate_tree_sitter_data(
|
||||
tree_sitter_data: &mut Arc<TreeSitterData>,
|
||||
snapshot: &text::BufferSnapshot,
|
||||
) {
|
||||
match Arc::get_mut(tree_sitter_data) {
|
||||
Some(tree_sitter_data) => tree_sitter_data.clear(snapshot),
|
||||
None => {
|
||||
let tree_sitter_data = TreeSitterData::new(snapshot);
|
||||
self.tree_sitter_data = Arc::new(tree_sitter_data)
|
||||
let new_tree_sitter_data = TreeSitterData::new(snapshot);
|
||||
*tree_sitter_data = Arc::new(new_tree_sitter_data)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1817,7 +1823,7 @@ impl Buffer {
|
||||
#[ztracing::instrument(skip_all)]
|
||||
pub fn reparse(&mut self, cx: &mut Context<Self>, may_block: bool) {
|
||||
if self.text.version() != *self.tree_sitter_data.version() {
|
||||
self.invalidate_tree_sitter_data(self.text.snapshot());
|
||||
Self::invalidate_tree_sitter_data(&mut self.tree_sitter_data, self.text.snapshot());
|
||||
}
|
||||
if self.reparse.is_some() {
|
||||
return;
|
||||
@@ -1898,7 +1904,7 @@ impl Buffer {
|
||||
self.was_changed();
|
||||
self.request_autoindent(cx, block_budget);
|
||||
self.parse_status.0.send(ParseStatus::Idle).unwrap();
|
||||
self.invalidate_tree_sitter_data(self.text.snapshot());
|
||||
Self::invalidate_tree_sitter_data(&mut self.tree_sitter_data, &self.text.snapshot());
|
||||
cx.emit(BufferEvent::Reparsed);
|
||||
cx.notify();
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ impl std::fmt::Debug for RowChunks {
|
||||
}
|
||||
|
||||
impl RowChunks {
|
||||
pub fn new(snapshot: text::BufferSnapshot, max_rows_per_chunk: u32) -> Self {
|
||||
pub fn new(snapshot: &text::BufferSnapshot, max_rows_per_chunk: u32) -> Self {
|
||||
let buffer_point_range = (0..snapshot.len()).to_point(&snapshot);
|
||||
let last_row = buffer_point_range.end.row;
|
||||
let chunks = (buffer_point_range.start.row..=last_row)
|
||||
|
||||
@@ -1047,7 +1047,7 @@ fn test_random_edits(
|
||||
log::info!("initial text:\n{}", buffer.text());
|
||||
|
||||
for _ in 0..operations {
|
||||
let prev_buffer = buffer.snapshot();
|
||||
let prev_buffer = buffer.snapshot().clone();
|
||||
let prev_syntax_map = syntax_map.snapshot();
|
||||
|
||||
buffer.randomly_edit(&mut rng, 3);
|
||||
|
||||
@@ -678,7 +678,7 @@ impl std::hash::Hash for DiffTransformHunkInfo {
|
||||
#[derive(Clone)]
|
||||
pub struct ExcerptInfo {
|
||||
pub id: ExcerptId,
|
||||
pub buffer: BufferSnapshot,
|
||||
pub buffer: Arc<BufferSnapshot>,
|
||||
pub buffer_id: BufferId,
|
||||
pub range: ExcerptRange<text::Anchor>,
|
||||
pub end_row: MultiBufferRow,
|
||||
@@ -739,7 +739,7 @@ struct Excerpt {
|
||||
/// The buffer being excerpted
|
||||
buffer_id: BufferId,
|
||||
/// A snapshot of the buffer being excerpted
|
||||
buffer: BufferSnapshot,
|
||||
buffer: Arc<BufferSnapshot>,
|
||||
/// The range of the buffer to be shown in the excerpt
|
||||
range: ExcerptRange<text::Anchor>,
|
||||
/// The last row in the excerpted slice of the buffer
|
||||
@@ -1849,6 +1849,7 @@ impl MultiBuffer {
|
||||
};
|
||||
|
||||
let mut excerpts = Vec::new();
|
||||
let buffer_snapshot = Arc::new(buffer_snapshot);
|
||||
while let Some((id, range)) = ranges.next() {
|
||||
let locator = Locator::between(&prev_locator, &next_locator);
|
||||
if let Err(ix) = buffer_state.excerpts.binary_search(&locator) {
|
||||
@@ -3013,6 +3014,21 @@ impl MultiBuffer {
|
||||
*has_deleted_file = false;
|
||||
*has_conflict = false;
|
||||
|
||||
if !diffs.is_empty() {
|
||||
let mut diffs_to_add = Vec::new();
|
||||
for (id, diff) in diffs {
|
||||
if diff.is_inverted || buffer_diff.get(id).is_none() {
|
||||
if diffs_to_add.capacity() == 0 {
|
||||
// we'd rather overallocate than reallocate as buffer diffs are quite big
|
||||
// meaning re-allocations will be fairly expensive
|
||||
diffs_to_add.reserve(diffs.len());
|
||||
}
|
||||
diffs_to_add.push((*id, diff.snapshot(cx)));
|
||||
}
|
||||
}
|
||||
buffer_diff.extend(diffs_to_add);
|
||||
}
|
||||
|
||||
let mut excerpts_to_edit = Vec::new();
|
||||
let mut non_text_state_updated = false;
|
||||
let mut edited = false;
|
||||
@@ -3052,19 +3068,7 @@ impl MultiBuffer {
|
||||
*non_text_state_update_count += 1;
|
||||
}
|
||||
|
||||
let diffs_to_add = diffs
|
||||
.iter()
|
||||
.filter_map(|(id, diff)| {
|
||||
if diff.is_inverted || buffer_diff.get(id).is_none() {
|
||||
Some((*id, diff.snapshot(cx)))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
buffer_diff.extend(diffs_to_add);
|
||||
|
||||
excerpts_to_edit.sort_unstable_by_key(|(locator, _, _)| *locator);
|
||||
excerpts_to_edit.sort_unstable_by_key(|&(locator, _, _)| locator);
|
||||
|
||||
let mut edits = Vec::new();
|
||||
let mut new_excerpts = SumTree::default();
|
||||
@@ -3075,7 +3079,6 @@ impl MultiBuffer {
|
||||
let old_excerpt = cursor.item().unwrap();
|
||||
let buffer = buffer.read(cx);
|
||||
let buffer_id = buffer.remote_id();
|
||||
|
||||
let mut new_excerpt;
|
||||
if buffer_edited {
|
||||
edits.extend(
|
||||
@@ -3103,13 +3106,13 @@ impl MultiBuffer {
|
||||
old_excerpt.id,
|
||||
locator.clone(),
|
||||
buffer_id,
|
||||
buffer.snapshot(),
|
||||
Arc::new(buffer.snapshot()),
|
||||
old_excerpt.range.clone(),
|
||||
old_excerpt.has_trailing_newline,
|
||||
);
|
||||
} else {
|
||||
new_excerpt = old_excerpt.clone();
|
||||
new_excerpt.buffer = buffer.snapshot();
|
||||
new_excerpt.buffer = Arc::new(buffer.snapshot());
|
||||
}
|
||||
|
||||
new_excerpts.push(new_excerpt, ());
|
||||
@@ -3981,7 +3984,7 @@ impl MultiBufferSnapshot {
|
||||
return None;
|
||||
}
|
||||
let excerpt = region.excerpt;
|
||||
cursor.next_excerpt();
|
||||
cursor.next_excerpt_forwards();
|
||||
Some(excerpt)
|
||||
})
|
||||
}
|
||||
@@ -4308,7 +4311,7 @@ impl MultiBufferSnapshot {
|
||||
{
|
||||
return None;
|
||||
}
|
||||
cursor.next_excerpt();
|
||||
cursor.next_excerpt_forwards();
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -4477,7 +4480,7 @@ impl MultiBufferSnapshot {
|
||||
self.excerpts
|
||||
.iter()
|
||||
.next()
|
||||
.map(|e| (&e.id, e.buffer_id, &e.buffer))
|
||||
.map(|e| (&e.id, e.buffer_id, &*e.buffer))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -5699,7 +5702,7 @@ impl MultiBufferSnapshot {
|
||||
) -> impl Iterator<Item = (ExcerptId, &BufferSnapshot, ExcerptRange<text::Anchor>)> {
|
||||
self.excerpts
|
||||
.iter()
|
||||
.map(|excerpt| (excerpt.id, &excerpt.buffer, excerpt.range.clone()))
|
||||
.map(|excerpt| (excerpt.id, &*excerpt.buffer, excerpt.range.clone()))
|
||||
}
|
||||
|
||||
fn cursor<'a, MBD, BD>(&'a self) -> MultiBufferCursor<'a, MBD, BD>
|
||||
@@ -5778,16 +5781,18 @@ impl MultiBufferSnapshot {
|
||||
});
|
||||
|
||||
if cursor
|
||||
.region()
|
||||
.is_some_and(|region| bounds.contains(®ion.range.start.key))
|
||||
.fetch_excerpt_with_range()
|
||||
.is_some_and(|(_, range)| bounds.contains(&range.start.key))
|
||||
{
|
||||
cursor.prev_excerpt();
|
||||
} else {
|
||||
cursor.seek_to_start_of_current_excerpt();
|
||||
}
|
||||
let mut prev_region = cursor.region().cloned();
|
||||
let mut prev_region = cursor
|
||||
.fetch_excerpt_with_range()
|
||||
.map(|(excerpt, _)| excerpt);
|
||||
|
||||
cursor.next_excerpt();
|
||||
cursor.next_excerpt_forwards();
|
||||
|
||||
iter::from_fn(move || {
|
||||
loop {
|
||||
@@ -5795,34 +5800,34 @@ impl MultiBufferSnapshot {
|
||||
return None;
|
||||
}
|
||||
|
||||
let next_region = cursor.region()?.clone();
|
||||
cursor.next_excerpt();
|
||||
if !bounds.contains(&next_region.range.start.key) {
|
||||
prev_region = Some(next_region);
|
||||
let (next_excerpt, next_range) = cursor.fetch_excerpt_with_range()?;
|
||||
cursor.next_excerpt_forwards();
|
||||
if !bounds.contains(&next_range.start.key) {
|
||||
prev_region = Some(next_excerpt);
|
||||
continue;
|
||||
}
|
||||
|
||||
let next_region_start = next_region.range.start.value.unwrap();
|
||||
let next_region_end = if let Some(region) = cursor.region() {
|
||||
region.range.start.value.unwrap()
|
||||
let next_region_start = next_range.start.value.unwrap();
|
||||
let next_region_end = if let Some((_, range)) = cursor.fetch_excerpt_with_range() {
|
||||
range.start.value.unwrap()
|
||||
} else {
|
||||
self.max_point()
|
||||
};
|
||||
|
||||
let prev = prev_region.as_ref().map(|region| ExcerptInfo {
|
||||
id: region.excerpt.id,
|
||||
buffer: region.excerpt.buffer.clone(),
|
||||
buffer_id: region.excerpt.buffer_id,
|
||||
range: region.excerpt.range.clone(),
|
||||
id: region.id,
|
||||
buffer: region.buffer.clone(),
|
||||
buffer_id: region.buffer_id,
|
||||
range: region.range.clone(),
|
||||
end_row: MultiBufferRow(next_region_start.row),
|
||||
});
|
||||
|
||||
let next = ExcerptInfo {
|
||||
id: next_region.excerpt.id,
|
||||
buffer: next_region.excerpt.buffer.clone(),
|
||||
buffer_id: next_region.excerpt.buffer_id,
|
||||
range: next_region.excerpt.range.clone(),
|
||||
end_row: if next_region.excerpt.has_trailing_newline {
|
||||
id: next_excerpt.id,
|
||||
buffer: next_excerpt.buffer.clone(),
|
||||
buffer_id: next_excerpt.buffer_id,
|
||||
range: next_excerpt.range.clone(),
|
||||
end_row: if next_excerpt.has_trailing_newline {
|
||||
MultiBufferRow(next_region_end.row - 1)
|
||||
} else {
|
||||
MultiBufferRow(next_region_end.row)
|
||||
@@ -5831,7 +5836,7 @@ impl MultiBufferSnapshot {
|
||||
|
||||
let row = MultiBufferRow(next_region_start.row);
|
||||
|
||||
prev_region = Some(next_region);
|
||||
prev_region = Some(next_excerpt);
|
||||
|
||||
return Some(ExcerptBoundary { row, prev, next });
|
||||
}
|
||||
@@ -6048,7 +6053,7 @@ impl MultiBufferSnapshot {
|
||||
cursor.next();
|
||||
Some(line_indents.map(move |(buffer_row, indent)| {
|
||||
let row = region_row + (buffer_row - region_buffer_row);
|
||||
(MultiBufferRow(row), indent, region_buffer)
|
||||
(MultiBufferRow(row), indent, region_buffer.as_ref())
|
||||
}))
|
||||
})
|
||||
.flatten()
|
||||
@@ -6092,7 +6097,7 @@ impl MultiBufferSnapshot {
|
||||
cursor.prev();
|
||||
Some(line_indents.map(move |(buffer_row, indent)| {
|
||||
let row = region_row + (buffer_row - region_buffer_row);
|
||||
(MultiBufferRow(row), indent, region_buffer)
|
||||
(MultiBufferRow(row), indent, region_buffer.as_ref())
|
||||
}))
|
||||
})
|
||||
.flatten()
|
||||
@@ -7029,8 +7034,26 @@ where
|
||||
|
||||
fn seek_to_start_of_current_excerpt(&mut self) {
|
||||
self.cached_region.take();
|
||||
self.diff_transforms.seek(self.excerpts.start(), Bias::Left);
|
||||
if self.diff_transforms.end().excerpt_dimension == *self.excerpts.start()
|
||||
|
||||
if self.diff_transforms.seek(self.excerpts.start(), Bias::Left)
|
||||
&& self.diff_transforms.start().excerpt_dimension < *self.excerpts.start()
|
||||
&& self.diff_transforms.next_item().is_some()
|
||||
{
|
||||
self.diff_transforms.next();
|
||||
}
|
||||
}
|
||||
|
||||
fn next_excerpt_forwards(&mut self) {
|
||||
self.excerpts.next();
|
||||
self.seek_to_start_of_current_excerpt_forward();
|
||||
}
|
||||
|
||||
fn seek_to_start_of_current_excerpt_forward(&mut self) {
|
||||
self.cached_region.take();
|
||||
|
||||
if self
|
||||
.diff_transforms
|
||||
.seek_forward(self.excerpts.start(), Bias::Left)
|
||||
&& self.diff_transforms.start().excerpt_dimension < *self.excerpts.start()
|
||||
&& self.diff_transforms.next_item().is_some()
|
||||
{
|
||||
@@ -7191,10 +7214,10 @@ where
|
||||
let mut end;
|
||||
let mut buffer_end;
|
||||
let has_trailing_newline;
|
||||
if self.diff_transforms.end().excerpt_dimension < self.excerpts.end() {
|
||||
let overshoot =
|
||||
self.diff_transforms.end().excerpt_dimension - *self.excerpts.start();
|
||||
end = self.diff_transforms.end().output_dimension.0;
|
||||
let transform_end = self.diff_transforms.end();
|
||||
if transform_end.excerpt_dimension < self.excerpts.end() {
|
||||
let overshoot = transform_end.excerpt_dimension - *self.excerpts.start();
|
||||
end = transform_end.output_dimension.0;
|
||||
buffer_end = buffer_context_start;
|
||||
buffer_end += overshoot;
|
||||
has_trailing_newline = false;
|
||||
@@ -7228,6 +7251,38 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn fetch_excerpt_with_range(&self) -> Option<(&'a Excerpt, Range<MBD>)> {
|
||||
let excerpt = self.excerpts.item()?;
|
||||
match self.diff_transforms.item()? {
|
||||
&DiffTransform::DeletedHunk { .. } => {
|
||||
let start = self.diff_transforms.start().output_dimension.0;
|
||||
let end = self.diff_transforms.end().output_dimension.0;
|
||||
Some((excerpt, start..end))
|
||||
}
|
||||
DiffTransform::BufferContent { .. } => {
|
||||
let mut start = self.diff_transforms.start().output_dimension.0;
|
||||
if self.diff_transforms.start().excerpt_dimension < *self.excerpts.start() {
|
||||
let overshoot =
|
||||
*self.excerpts.start() - self.diff_transforms.start().excerpt_dimension;
|
||||
start += overshoot;
|
||||
}
|
||||
|
||||
let mut end;
|
||||
let transform_end = self.diff_transforms.end();
|
||||
if transform_end.excerpt_dimension < self.excerpts.end() {
|
||||
end = transform_end.output_dimension.0;
|
||||
} else {
|
||||
let overshoot =
|
||||
self.excerpts.end() - self.diff_transforms.start().excerpt_dimension;
|
||||
end = self.diff_transforms.start().output_dimension.0;
|
||||
end += overshoot;
|
||||
};
|
||||
|
||||
Some((excerpt, start..end))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn excerpt(&self) -> Option<&'a Excerpt> {
|
||||
self.excerpts.item()
|
||||
}
|
||||
@@ -7238,7 +7293,7 @@ impl Excerpt {
|
||||
id: ExcerptId,
|
||||
locator: Locator,
|
||||
buffer_id: BufferId,
|
||||
buffer: BufferSnapshot,
|
||||
buffer: Arc<BufferSnapshot>,
|
||||
range: ExcerptRange<text::Anchor>,
|
||||
has_trailing_newline: bool,
|
||||
) -> Self {
|
||||
|
||||
@@ -78,7 +78,7 @@ const MAX_ROWS_IN_A_CHUNK: u32 = 50;
|
||||
|
||||
impl BufferInlayHints {
|
||||
pub fn new(buffer: &Entity<Buffer>, cx: &mut App) -> Self {
|
||||
let chunks = RowChunks::new(buffer.read(cx).text_snapshot(), MAX_ROWS_IN_A_CHUNK);
|
||||
let chunks = RowChunks::new(buffer.read(cx).as_text_snapshot(), MAX_ROWS_IN_A_CHUNK);
|
||||
|
||||
Self {
|
||||
hints_by_chunks: vec![None; chunks.len()],
|
||||
|
||||
@@ -83,9 +83,6 @@ impl<K: Clone + Ord, V: Clone> TreeMap<K, V> {
|
||||
.into_iter()
|
||||
.map(|(key, value)| Edit::Insert(MapEntry { key, value }))
|
||||
.collect();
|
||||
if edits.is_empty() {
|
||||
return;
|
||||
}
|
||||
self.0.edit(edits, ());
|
||||
}
|
||||
|
||||
|
||||
+10
-6
@@ -104,16 +104,16 @@ impl From<BufferId> for u64 {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct BufferSnapshot {
|
||||
replica_id: ReplicaId,
|
||||
remote_id: BufferId,
|
||||
visible_text: Rope,
|
||||
deleted_text: Rope,
|
||||
line_ending: LineEnding,
|
||||
undo_map: UndoMap,
|
||||
fragments: SumTree<Fragment>,
|
||||
insertions: SumTree<InsertionFragment>,
|
||||
insertion_slices: TreeSet<InsertionSlice>,
|
||||
undo_map: UndoMap,
|
||||
pub version: clock::Global,
|
||||
remote_id: BufferId,
|
||||
replica_id: ReplicaId,
|
||||
line_ending: LineEnding,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -780,8 +780,12 @@ impl Buffer {
|
||||
self.version.clone()
|
||||
}
|
||||
|
||||
pub fn snapshot(&self) -> BufferSnapshot {
|
||||
self.snapshot.clone()
|
||||
pub fn snapshot(&self) -> &BufferSnapshot {
|
||||
&self.snapshot
|
||||
}
|
||||
|
||||
pub fn into_snapshot(self) -> BufferSnapshot {
|
||||
self.snapshot
|
||||
}
|
||||
|
||||
pub fn branch(&self) -> Self {
|
||||
|
||||
Reference in new issue
Block a user