editor: Shrink DisplayMapSnapshot from 824 to 256 bytes (#39568)

We have unnecessary clones for the fields here as most of the snapshots
contain the others hierarchically.

Release Notes:

- N/A *or* Added/Fixed/Improved ...
This commit is contained in:
Lukas Wirth
2025-10-06 08:08:49 +00:00
committed by GitHub
parent 9c7369f54d
commit 2bfcd60b88
48 changed files with 594 additions and 543 deletions
+63 -63
View File
@@ -1387,7 +1387,7 @@ impl Motion {
let end = selection.end.to_point(map);
let start_row = MultiBufferRow(selection.start.to_point(map).row);
if end.row > start.row {
selection.end = Point::new(start_row.0, map.buffer_snapshot.line_len(start_row))
selection.end = Point::new(start_row.0, map.buffer_snapshot().line_len(start_row))
.to_display_point(map);
// a bit of a hack, we need `cw` on a blank line to not delete the newline,
@@ -1537,11 +1537,11 @@ pub(crate) fn start_of_relative_buffer_row(
) -> DisplayPoint {
let start = map.display_point_to_fold_point(point, Bias::Left);
let target = start.row() as isize + times;
let new_row = (target.max(0) as u32).min(map.fold_snapshot.max_point().row());
let new_row = (target.max(0) as u32).min(map.fold_snapshot().max_point().row());
map.clip_point(
map.fold_point_to_display_point(
map.fold_snapshot
map.fold_snapshot()
.clip_point(FoldPoint::new(new_row, 0), Bias::Right),
),
Bias::Right,
@@ -1571,7 +1571,7 @@ fn up_down_buffer_rows(
let start = map.display_point_to_fold_point(point, Bias::Left);
let begin_folded_line = map.fold_point_to_display_point(
map.fold_snapshot
map.fold_snapshot()
.clip_point(FoldPoint::new(start.row(), 0), Bias::Left),
);
let select_nth_wrapped_row = point.row().0 - begin_folded_line.row().0;
@@ -1588,10 +1588,10 @@ fn up_down_buffer_rows(
};
let target = start.row() as isize + times;
let new_row = (target.max(0) as u32).min(map.fold_snapshot.max_point().row());
let new_row = (target.max(0) as u32).min(map.fold_snapshot().max_point().row());
let mut begin_folded_line = map.fold_point_to_display_point(
map.fold_snapshot
map.fold_snapshot()
.clip_point(FoldPoint::new(new_row, 0), bias),
);
@@ -1697,7 +1697,7 @@ pub(crate) fn next_word_start(
times: usize,
) -> DisplayPoint {
let classifier = map
.buffer_snapshot
.buffer_snapshot()
.char_classifier_at(point.to_point(map))
.ignore_punctuation(ignore_punctuation);
for _ in 0..times {
@@ -1731,7 +1731,7 @@ pub(crate) fn next_word_end(
always_advance: bool,
) -> DisplayPoint {
let classifier = map
.buffer_snapshot
.buffer_snapshot()
.char_classifier_at(point.to_point(map))
.ignore_punctuation(ignore_punctuation);
for _ in 0..times {
@@ -1779,7 +1779,7 @@ fn previous_word_start(
times: usize,
) -> DisplayPoint {
let classifier = map
.buffer_snapshot
.buffer_snapshot()
.char_classifier_at(point.to_point(map))
.ignore_punctuation(ignore_punctuation);
for _ in 0..times {
@@ -1811,19 +1811,19 @@ fn previous_word_end(
times: usize,
) -> DisplayPoint {
let classifier = map
.buffer_snapshot
.buffer_snapshot()
.char_classifier_at(point.to_point(map))
.ignore_punctuation(ignore_punctuation);
let mut point = point.to_point(map);
if point.column < map.buffer_snapshot.line_len(MultiBufferRow(point.row))
&& let Some(ch) = map.buffer_snapshot.chars_at(point).next()
if point.column < map.buffer_snapshot().line_len(MultiBufferRow(point.row))
&& let Some(ch) = map.buffer_snapshot().chars_at(point).next()
{
point.column += ch.len_utf8() as u32;
}
for _ in 0..times {
let new_point = movement::find_preceding_boundary_point(
&map.buffer_snapshot,
&map.buffer_snapshot(),
point,
FindRange::MultiLine,
|left, right| {
@@ -1854,7 +1854,7 @@ fn next_subword_start(
times: usize,
) -> DisplayPoint {
let classifier = map
.buffer_snapshot
.buffer_snapshot()
.char_classifier_at(point.to_point(map))
.ignore_punctuation(ignore_punctuation);
for _ in 0..times {
@@ -1891,7 +1891,7 @@ pub(crate) fn next_subword_end(
allow_cross_newline: bool,
) -> DisplayPoint {
let classifier = map
.buffer_snapshot
.buffer_snapshot()
.char_classifier_at(point.to_point(map))
.ignore_punctuation(ignore_punctuation);
for _ in 0..times {
@@ -1942,7 +1942,7 @@ fn previous_subword_start(
times: usize,
) -> DisplayPoint {
let classifier = map
.buffer_snapshot
.buffer_snapshot()
.char_classifier_at(point.to_point(map))
.ignore_punctuation(ignore_punctuation);
for _ in 0..times {
@@ -1986,19 +1986,19 @@ fn previous_subword_end(
times: usize,
) -> DisplayPoint {
let classifier = map
.buffer_snapshot
.buffer_snapshot()
.char_classifier_at(point.to_point(map))
.ignore_punctuation(ignore_punctuation);
let mut point = point.to_point(map);
if point.column < map.buffer_snapshot.line_len(MultiBufferRow(point.row))
&& let Some(ch) = map.buffer_snapshot.chars_at(point).next()
if point.column < map.buffer_snapshot().line_len(MultiBufferRow(point.row))
&& let Some(ch) = map.buffer_snapshot().chars_at(point).next()
{
point.column += ch.len_utf8() as u32;
}
for _ in 0..times {
let new_point = movement::find_preceding_boundary_point(
&map.buffer_snapshot,
&map.buffer_snapshot(),
point,
FindRange::MultiLine,
|left, right| {
@@ -2034,7 +2034,7 @@ pub(crate) fn first_non_whitespace(
from: DisplayPoint,
) -> DisplayPoint {
let mut start_offset = start_of_line(map, display_lines, from).to_offset(map, Bias::Left);
let classifier = map.buffer_snapshot.char_classifier_at(from.to_point(map));
let classifier = map.buffer_snapshot().char_classifier_at(from.to_point(map));
for (ch, offset) in map.buffer_chars_at(start_offset) {
if ch == '\n' {
return from;
@@ -2056,7 +2056,7 @@ pub(crate) fn last_non_whitespace(
count: usize,
) -> DisplayPoint {
let mut end_of_line = end_of_line(map, false, from, count).to_offset(map, Bias::Left);
let classifier = map.buffer_snapshot.char_classifier_at(from.to_point(map));
let classifier = map.buffer_snapshot().char_classifier_at(from.to_point(map));
// NOTE: depending on clip_at_line_end we may already be one char back from the end.
if let Some((ch, _)) = map.buffer_chars_at(end_of_line).next()
@@ -2112,7 +2112,7 @@ pub(crate) fn middle_of_line(
} else {
let mut buffer_point = point.to_point(map);
buffer_point.column = (map
.buffer_snapshot
.buffer_snapshot()
.line_len(MultiBufferRow(buffer_point.row)) as f64
* percent) as u32;
@@ -2144,7 +2144,7 @@ pub(crate) fn sentence_backwards(
point: DisplayPoint,
mut times: usize,
) -> DisplayPoint {
let mut start = point.to_point(map).to_offset(&map.buffer_snapshot);
let mut start = point.to_point(map).to_offset(&map.buffer_snapshot());
let mut chars = map.reverse_buffer_chars_at(start).peekable();
let mut was_newline = map
@@ -2170,7 +2170,7 @@ pub(crate) fn sentence_backwards(
if times == 0 || offset == 0 {
return map.clip_point(
start_of_next_sentence
.to_offset(&map.buffer_snapshot)
.to_offset(&map.buffer_snapshot())
.to_display_point(map),
Bias::Left,
);
@@ -2190,7 +2190,7 @@ pub(crate) fn sentence_forwards(
point: DisplayPoint,
mut times: usize,
) -> DisplayPoint {
let start = point.to_point(map).to_offset(&map.buffer_snapshot);
let start = point.to_point(map).to_offset(&map.buffer_snapshot());
let mut chars = map.buffer_chars_at(start).peekable();
let mut was_newline = map
@@ -2218,7 +2218,7 @@ pub(crate) fn sentence_forwards(
if times == 0 {
return map.clip_point(
start_of_next_sentence
.to_offset(&map.buffer_snapshot)
.to_offset(&map.buffer_snapshot())
.to_display_point(map),
Bias::Right,
);
@@ -2238,7 +2238,7 @@ fn next_non_blank(map: &DisplaySnapshot, start: usize) -> usize {
}
}
map.buffer_snapshot.len()
map.buffer_snapshot().len()
}
// given the offset after a ., !, or ? find the start of the next sentence.
@@ -2263,12 +2263,12 @@ fn start_of_next_sentence(map: &DisplaySnapshot, end_of_sentence: usize) -> Opti
}
}
Some(map.buffer_snapshot.len())
Some(map.buffer_snapshot().len())
}
fn go_to_line(map: &DisplaySnapshot, display_point: DisplayPoint, line: usize) -> DisplayPoint {
let point = map.display_point_to_point(display_point, Bias::Left);
let Some(mut excerpt) = map.buffer_snapshot.excerpt_containing(point..point) else {
let Some(mut excerpt) = map.buffer_snapshot().excerpt_containing(point..point) else {
return display_point;
};
let offset = excerpt.buffer().point_to_offset(
@@ -2279,12 +2279,12 @@ fn go_to_line(map: &DisplaySnapshot, display_point: DisplayPoint, line: usize) -
let buffer_range = excerpt.buffer_range();
if offset >= buffer_range.start && offset <= buffer_range.end {
let point = map
.buffer_snapshot
.buffer_snapshot()
.offset_to_point(excerpt.map_offset_from_buffer(offset));
return map.clip_point(map.point_to_display_point(point, Bias::Left), Bias::Left);
}
let mut last_position = None;
for (excerpt, buffer, range) in map.buffer_snapshot.excerpts() {
for (excerpt, buffer, range) in map.buffer_snapshot().excerpts() {
let excerpt_range = language::ToOffset::to_offset(&range.context.start, buffer)
..language::ToOffset::to_offset(&range.context.end, buffer);
if offset >= excerpt_range.start && offset <= excerpt_range.end {
@@ -2303,12 +2303,12 @@ fn go_to_line(map: &DisplaySnapshot, display_point: DisplayPoint, line: usize) -
}
}
let mut last_point = last_position.unwrap().to_point(&map.buffer_snapshot);
let mut last_point = last_position.unwrap().to_point(&map.buffer_snapshot());
last_point.column = point.column;
map.clip_point(
map.point_to_display_point(
map.buffer_snapshot.clip_point(point, Bias::Left),
map.buffer_snapshot().clip_point(point, Bias::Left),
Bias::Left,
),
Bias::Left,
@@ -2330,7 +2330,7 @@ fn start_of_document(
map.clip_point(
map.point_to_display_point(
map.buffer_snapshot.clip_point(first_point, Bias::Left),
map.buffer_snapshot().clip_point(first_point, Bias::Left),
Bias::Left,
),
Bias::Left,
@@ -2346,12 +2346,12 @@ fn end_of_document(
return go_to_line(map, display_point, times);
};
let point = map.display_point_to_point(display_point, Bias::Left);
let mut last_point = map.buffer_snapshot.max_point();
let mut last_point = map.buffer_snapshot().max_point();
last_point.column = point.column;
map.clip_point(
map.point_to_display_point(
map.buffer_snapshot.clip_point(last_point, Bias::Left),
map.buffer_snapshot().clip_point(last_point, Bias::Left),
Bias::Left,
),
Bias::Left,
@@ -2364,7 +2364,7 @@ fn matching_tag(map: &DisplaySnapshot, head: DisplayPoint) -> Option<DisplayPoin
if head > outer.start && head < inner.start {
let mut offset = inner.end.to_offset(map, Bias::Left);
for c in map.buffer_snapshot.chars_at(offset) {
for c in map.buffer_snapshot().chars_at(offset) {
if c == '/' || c == '\n' || c == '>' {
return Some(offset.to_display_point(map));
}
@@ -2372,7 +2372,7 @@ fn matching_tag(map: &DisplaySnapshot, head: DisplayPoint) -> Option<DisplayPoin
}
} else {
let mut offset = outer.start.to_offset(map, Bias::Left);
for c in map.buffer_snapshot.chars_at(offset) {
for c in map.buffer_snapshot().chars_at(offset) {
offset += c.len_utf8();
if c == '<' || c == '\n' {
return Some(offset.to_display_point(map));
@@ -2387,7 +2387,7 @@ fn matching(map: &DisplaySnapshot, display_point: DisplayPoint) -> DisplayPoint
// https://github.com/vim/vim/blob/1d87e11a1ef201b26ed87585fba70182ad0c468a/runtime/doc/motion.txt#L1200
let display_point = map.clip_at_line_end(display_point);
let point = display_point.to_point(map);
let offset = point.to_offset(&map.buffer_snapshot);
let offset = point.to_offset(&map.buffer_snapshot());
// Ensure the range is contained by the current line.
let mut line_end = map.next_line_boundary(point).0;
@@ -2396,7 +2396,7 @@ fn matching(map: &DisplaySnapshot, display_point: DisplayPoint) -> DisplayPoint
}
if let Some((opening_range, closing_range)) = map
.buffer_snapshot
.buffer_snapshot()
.innermost_enclosing_bracket_ranges(offset..offset, None)
{
if opening_range.contains(&offset) {
@@ -2409,17 +2409,17 @@ fn matching(map: &DisplaySnapshot, display_point: DisplayPoint) -> DisplayPoint
let line_range = map.prev_line_boundary(point).0..line_end;
let visible_line_range =
line_range.start..Point::new(line_range.end.row, line_range.end.column.saturating_sub(1));
let ranges = map.buffer_snapshot.bracket_ranges(visible_line_range);
let ranges = map.buffer_snapshot().bracket_ranges(visible_line_range);
if let Some(ranges) = ranges {
let line_range = line_range.start.to_offset(&map.buffer_snapshot)
..line_range.end.to_offset(&map.buffer_snapshot);
let line_range = line_range.start.to_offset(&map.buffer_snapshot())
..line_range.end.to_offset(&map.buffer_snapshot());
let mut closest_pair_destination = None;
let mut closest_distance = usize::MAX;
for (open_range, close_range) in ranges {
if map.buffer_snapshot.chars_at(open_range.start).next() == Some('<') {
if map.buffer_snapshot().chars_at(open_range.start).next() == Some('<') {
if offset > open_range.start && offset < close_range.start {
let mut chars = map.buffer_snapshot.chars_at(close_range.start);
let mut chars = map.buffer_snapshot().chars_at(close_range.start);
if (Some('/'), Some('>')) == (chars.next(), chars.next()) {
return display_point;
}
@@ -2473,7 +2473,7 @@ fn matching(map: &DisplaySnapshot, display_point: DisplayPoint) -> DisplayPoint
//
// https://neovim.io/doc/user/motion.html#N%25
fn go_to_percentage(map: &DisplaySnapshot, point: DisplayPoint, count: usize) -> DisplayPoint {
let total_lines = map.buffer_snapshot.max_point().row + 1;
let total_lines = map.buffer_snapshot().max_point().row + 1;
let target_line = (count * total_lines as usize).div_ceil(100);
let target_point = DisplayPoint::new(
DisplayRow(target_line.saturating_sub(1) as u32),
@@ -2491,16 +2491,16 @@ fn unmatched_forward(
for _ in 0..times {
// https://github.com/vim/vim/blob/1d87e11a1ef201b26ed87585fba70182ad0c468a/runtime/doc/motion.txt#L1245
let point = display_point.to_point(map);
let offset = point.to_offset(&map.buffer_snapshot);
let offset = point.to_offset(&map.buffer_snapshot());
let ranges = map.buffer_snapshot.enclosing_bracket_ranges(point..point);
let ranges = map.buffer_snapshot().enclosing_bracket_ranges(point..point);
let Some(ranges) = ranges else { break };
let mut closest_closing_destination = None;
let mut closest_distance = usize::MAX;
for (_, close_range) in ranges {
if close_range.start > offset {
let mut chars = map.buffer_snapshot.chars_at(close_range.start);
let mut chars = map.buffer_snapshot().chars_at(close_range.start);
if Some(char) == chars.next() {
let distance = close_range.start - offset;
if distance < closest_distance {
@@ -2532,9 +2532,9 @@ fn unmatched_backward(
for _ in 0..times {
// https://github.com/vim/vim/blob/1d87e11a1ef201b26ed87585fba70182ad0c468a/runtime/doc/motion.txt#L1239
let point = display_point.to_point(map);
let offset = point.to_offset(&map.buffer_snapshot);
let offset = point.to_offset(&map.buffer_snapshot());
let ranges = map.buffer_snapshot.enclosing_bracket_ranges(point..point);
let ranges = map.buffer_snapshot().enclosing_bracket_ranges(point..point);
let Some(ranges) = ranges else {
break;
};
@@ -2544,7 +2544,7 @@ fn unmatched_backward(
for (start_range, _) in ranges {
if start_range.start < offset {
let mut chars = map.buffer_snapshot.chars_at(start_range.start);
let mut chars = map.buffer_snapshot().chars_at(start_range.start);
if Some(char) == chars.next() {
let distance = offset - start_range.start;
if distance < closest_distance {
@@ -2629,7 +2629,7 @@ fn find_backward(
to = new_to;
}
let next = map.buffer_snapshot.chars_at(to.to_point(map)).next();
let next = map.buffer_snapshot().chars_at(to.to_point(map)).next();
if next.is_some() && is_character_match(target, next.unwrap(), smartcase) {
if after {
*to.column_mut() += 1;
@@ -2850,13 +2850,13 @@ fn method_motion(
direction: Direction,
is_start: bool,
) -> DisplayPoint {
let Some((_, _, buffer)) = map.buffer_snapshot.as_singleton() else {
let Some((_, _, buffer)) = map.buffer_snapshot().as_singleton() else {
return display_point;
};
for _ in 0..times {
let point = map.display_point_to_point(display_point, Bias::Left);
let offset = point.to_offset(&map.buffer_snapshot);
let offset = point.to_offset(&map.buffer_snapshot());
let range = if direction == Direction::Prev {
0..offset
} else {
@@ -2900,13 +2900,13 @@ fn comment_motion(
times: usize,
direction: Direction,
) -> DisplayPoint {
let Some((_, _, buffer)) = map.buffer_snapshot.as_singleton() else {
let Some((_, _, buffer)) = map.buffer_snapshot().as_singleton() else {
return display_point;
};
for _ in 0..times {
let point = map.display_point_to_point(display_point, Bias::Left);
let offset = point.to_offset(&map.buffer_snapshot);
let offset = point.to_offset(&map.buffer_snapshot());
let range = if direction == Direction::Prev {
0..offset
} else {
@@ -2956,22 +2956,22 @@ fn section_motion(
direction: Direction,
is_start: bool,
) -> DisplayPoint {
if map.buffer_snapshot.as_singleton().is_some() {
if map.buffer_snapshot().as_singleton().is_some() {
for _ in 0..times {
let offset = map
.display_point_to_point(display_point, Bias::Left)
.to_offset(&map.buffer_snapshot);
.to_offset(&map.buffer_snapshot());
let range = if direction == Direction::Prev {
0..offset
} else {
offset..map.buffer_snapshot.len()
offset..map.buffer_snapshot().len()
};
// we set a max start depth here because we want a section to only be "top level"
// similar to vim's default of '{' in the first column.
// (and without it, ]] at the start of editor.rs is -very- slow)
let mut possibilities = map
.buffer_snapshot
.buffer_snapshot()
.text_object_ranges(range, language::TreeSitterOptions::max_start_depth(3))
.filter(|(_, object)| {
matches!(
@@ -3003,7 +3003,7 @@ fn section_motion(
let offset = if direction == Direction::Prev {
possibilities.max().unwrap_or(0)
} else {
possibilities.min().unwrap_or(map.buffer_snapshot.len())
possibilities.min().unwrap_or(map.buffer_snapshot().len())
};
let new_point = map.clip_point(offset.to_display_point(map), Bias::Left);