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

Lukas Wirth created

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 ...

Change summary

crates/agent_ui/src/acp/message_editor.rs         |  16 
crates/agent_ui/src/agent_diff.rs                 |   4 
crates/agent_ui/src/inline_assistant.rs           |  12 
crates/collab/src/tests/channel_buffer_tests.rs   |   4 
crates/collab_ui/src/channel_view.rs              |   4 
crates/debugger_ui/src/stack_trace_view.rs        |  10 
crates/debugger_ui/src/tests/debugger_panel.rs    |   4 
crates/debugger_ui/src/tests/stack_frame_list.rs  |   8 
crates/diagnostics/src/diagnostic_renderer.rs     |   4 
crates/diagnostics/src/diagnostics_tests.rs       |  12 
crates/editor/src/display_map.rs                  | 188 +++++++-----
crates/editor/src/display_map/block_map.rs        |   4 
crates/editor/src/display_map/fold_map.rs         |   2 
crates/editor/src/display_map/wrap_map.rs         |   2 
crates/editor/src/editor.rs                       | 237 ++++++++--------
crates/editor/src/editor_tests.rs                 |  22 
crates/editor/src/element.rs                      |  60 ++--
crates/editor/src/highlight_matching_bracket.rs   |  12 
crates/editor/src/hover_links.rs                  |  10 
crates/editor/src/hover_popover.rs                |  50 +-
crates/editor/src/indent_guides.rs                |  26 
crates/editor/src/items.rs                        |   3 
crates/editor/src/mouse_context_menu.rs           |   3 
crates/editor/src/movement.rs                     |  62 ++--
crates/editor/src/scroll.rs                       |   4 
crates/editor/src/selections_collection.rs        |   8 
crates/editor/src/tasks.rs                        |   4 
crates/editor/src/test.rs                         |   2 
crates/editor/src/test/editor_lsp_test_context.rs |   6 
crates/editor/src/test/editor_test_context.rs     |   6 
crates/git_ui/src/project_diff.rs                 |   4 
crates/language_tools/src/syntax_tree_view.rs     |   2 
crates/vim/src/command.rs                         |  20 
crates/vim/src/helix.rs                           |  10 
crates/vim/src/helix/boundary.rs                  |  24 
crates/vim/src/helix/paste.rs                     |   4 
crates/vim/src/motion.rs                          | 126 ++++----
crates/vim/src/normal/change.rs                   |   4 
crates/vim/src/normal/delete.rs                   |   9 
crates/vim/src/normal/mark.rs                     |  10 
crates/vim/src/normal/paste.rs                    |   6 
crates/vim/src/normal/search.rs                   |   5 
crates/vim/src/object.rs                          |  50 ++-
crates/vim/src/replace.rs                         |  34 +-
crates/vim/src/surrounds.rs                       |   6 
crates/vim/src/test.rs                            |   4 
crates/vim/src/vim.rs                             |   9 
crates/vim/src/visual.rs                          |  21 
48 files changed, 594 insertions(+), 543 deletions(-)

Detailed changes

crates/agent_ui/src/acp/message_editor.rs 🔗

@@ -290,18 +290,18 @@ impl MessageEditor {
         let snapshot = self
             .editor
             .update(cx, |editor, cx| editor.snapshot(window, cx));
-        let Some((excerpt_id, _, _)) = snapshot.buffer_snapshot.as_singleton() else {
+        let Some((excerpt_id, _, _)) = snapshot.buffer_snapshot().as_singleton() else {
             return Task::ready(());
         };
         let Some(start_anchor) = snapshot
-            .buffer_snapshot
+            .buffer_snapshot()
             .anchor_in_excerpt(*excerpt_id, start)
         else {
             return Task::ready(());
         };
         let end_anchor = snapshot
-            .buffer_snapshot
-            .anchor_before(start_anchor.to_offset(&snapshot.buffer_snapshot) + content_len + 1);
+            .buffer_snapshot()
+            .anchor_before(start_anchor.to_offset(&snapshot.buffer_snapshot()) + content_len + 1);
 
         let crease = if let MentionUri::File { abs_path } = &mention_uri
             && let Some(extension) = abs_path.extension()
@@ -718,7 +718,7 @@ impl MessageEditor {
                             continue;
                         };
 
-                        let crease_range = crease.range().to_offset(&snapshot.buffer_snapshot);
+                        let crease_range = crease.range().to_offset(&snapshot.buffer_snapshot());
                         if crease_range.start > ix {
                             //todo(): Custom slash command ContentBlock?
                             // let chunk = if prevent_slash_commands
@@ -865,11 +865,11 @@ impl MessageEditor {
                 self.editor.update(cx, |message_editor, cx| {
                     let snapshot = message_editor.snapshot(window, cx);
                     let (excerpt_id, _, buffer_snapshot) =
-                        snapshot.buffer_snapshot.as_singleton().unwrap();
+                        snapshot.buffer_snapshot().as_singleton().unwrap();
 
                     let text_anchor = buffer_snapshot.anchor_before(buffer_snapshot.len());
                     let multibuffer_anchor = snapshot
-                        .buffer_snapshot
+                        .buffer_snapshot()
                         .anchor_in_excerpt(*excerpt_id, text_anchor);
                     message_editor.edit(
                         [(
@@ -1550,7 +1550,7 @@ impl MentionSet {
 
     fn remove_invalid(&mut self, snapshot: EditorSnapshot) {
         for (crease_id, crease) in snapshot.crease_snapshot.creases() {
-            if !crease.range().start.is_valid(&snapshot.buffer_snapshot) {
+            if !crease.range().start.is_valid(&snapshot.buffer_snapshot()) {
                 self.mentions.remove(&crease_id);
             }
         }

crates/agent_ui/src/agent_diff.rs 🔗

@@ -846,7 +846,7 @@ fn render_diff_hunk_controls(
                                 editor.update(cx, |editor, cx| {
                                     let snapshot = editor.snapshot(window, cx);
                                     let position =
-                                        hunk_range.end.to_point(&snapshot.buffer_snapshot);
+                                        hunk_range.end.to_point(&snapshot.buffer_snapshot());
                                     editor.go_to_hunk_before_or_after_position(
                                         &snapshot,
                                         position,
@@ -882,7 +882,7 @@ fn render_diff_hunk_controls(
                                 editor.update(cx, |editor, cx| {
                                     let snapshot = editor.snapshot(window, cx);
                                     let point =
-                                        hunk_range.start.to_point(&snapshot.buffer_snapshot);
+                                        hunk_range.start.to_point(&snapshot.buffer_snapshot());
                                     editor.go_to_hunk_before_or_after_position(
                                         &snapshot,
                                         point,

crates/agent_ui/src/inline_assistant.rs 🔗

@@ -382,7 +382,7 @@ impl InlineAssistant {
         if let Some(editor_assists) = self.assists_by_editor.get(&editor.downgrade()) {
             for assist_id in &editor_assists.assist_ids {
                 let assist = &self.assists[assist_id];
-                let range = assist.range.to_point(&snapshot.buffer_snapshot);
+                let range = assist.range.to_point(&snapshot.buffer_snapshot());
                 if range.start.row <= newest_selection.start.row
                     && newest_selection.end.row <= range.end.row
                 {
@@ -402,16 +402,16 @@ impl InlineAssistant {
                     selection.end.row -= 1;
                 }
                 selection.end.column = snapshot
-                    .buffer_snapshot
+                    .buffer_snapshot()
                     .line_len(MultiBufferRow(selection.end.row));
             } else if let Some(fold) =
                 snapshot.crease_for_buffer_row(MultiBufferRow(selection.end.row))
             {
                 selection.start = fold.range().start;
                 selection.end = fold.range().end;
-                if MultiBufferRow(selection.end.row) < snapshot.buffer_snapshot.max_row() {
+                if MultiBufferRow(selection.end.row) < snapshot.buffer_snapshot().max_row() {
                     let chars = snapshot
-                        .buffer_snapshot
+                        .buffer_snapshot()
                         .chars_at(Point::new(selection.end.row + 1, 0));
 
                     for c in chars {
@@ -427,7 +427,7 @@ impl InlineAssistant {
                         {
                             selection.end.row += 1;
                             selection.end.column = snapshot
-                                .buffer_snapshot
+                                .buffer_snapshot()
                                 .line_len(MultiBufferRow(selection.end.row));
                         }
                     }
@@ -447,7 +447,7 @@ impl InlineAssistant {
             }
             selections.push(selection);
         }
-        let snapshot = &snapshot.buffer_snapshot;
+        let snapshot = &snapshot.buffer_snapshot();
         let newest_selection = newest_selection.unwrap();
 
         let mut codegen_ranges = Vec::new();

crates/collab/src/tests/channel_buffer_tests.rs 🔗

@@ -323,8 +323,8 @@ fn assert_remote_selections(
             let CollaboratorId::PeerId(peer_id) = s.collaborator_id else {
                 panic!("unexpected collaborator id");
             };
-            let start = s.selection.start.to_offset(&snapshot.buffer_snapshot);
-            let end = s.selection.end.to_offset(&snapshot.buffer_snapshot);
+            let start = s.selection.start.to_offset(snapshot.buffer_snapshot());
+            let end = s.selection.end.to_offset(snapshot.buffer_snapshot());
             let user_id = collaborators.get(&peer_id).unwrap().user_id;
             let participant_index = hub.user_participant_indices(cx).get(&user_id).copied();
             (participant_index, start..end)

crates/collab_ui/src/channel_view.rs 🔗

@@ -248,7 +248,7 @@ impl ChannelView {
             .editor
             .update(cx, |editor, cx| editor.snapshot(window, cx));
 
-        if let Some(outline) = snapshot.buffer_snapshot.outline(None)
+        if let Some(outline) = snapshot.buffer_snapshot().outline(None)
             && let Some(item) = outline
                 .items
                 .iter()
@@ -305,7 +305,7 @@ impl ChannelView {
 
         let mut closest_heading = None;
 
-        if let Some(outline) = snapshot.buffer_snapshot.outline(None) {
+        if let Some(outline) = snapshot.buffer_snapshot().outline(None) {
             for item in outline.items {
                 if item.range.start.to_display_point(&snapshot) > position {
                     break;

crates/debugger_ui/src/stack_trace_view.rs 🔗

@@ -59,7 +59,7 @@ impl StackTraceView {
 
                     editor
                         .snapshot(window, cx)
-                        .buffer_snapshot
+                        .buffer_snapshot()
                         .excerpt_containing(position..position)
                         .map(|excerpt| excerpt.id())
                 });
@@ -259,7 +259,7 @@ impl StackTraceView {
             let mut is_first = true;
 
             for (_, highlight) in self.highlights.iter().skip(active_idx) {
-                let position = highlight.to_point(&snapshot.buffer_snapshot);
+                let position = highlight.to_point(&snapshot.buffer_snapshot());
                 let color = if is_first {
                     is_first = false;
                     first_color
@@ -268,11 +268,11 @@ impl StackTraceView {
                 };
 
                 let start = snapshot
-                    .buffer_snapshot
+                    .buffer_snapshot()
                     .clip_point(Point::new(position.row, 0), Bias::Left);
                 let end = start + Point::new(1, 0);
-                let start = snapshot.buffer_snapshot.anchor_before(start);
-                let end = snapshot.buffer_snapshot.anchor_before(end);
+                let start = snapshot.buffer_snapshot().anchor_before(start);
+                let end = snapshot.buffer_snapshot().anchor_before(end);
                 editor.highlight_rows::<DebugStackFrameLine>(
                     start..end,
                     color,

crates/debugger_ui/src/tests/debugger_panel.rs 🔗

@@ -1604,7 +1604,7 @@ async fn test_active_debug_line_setting(executor: BackgroundExecutor, cx: &mut T
 
         let point = editor
             .snapshot(window, cx)
-            .buffer_snapshot
+            .buffer_snapshot()
             .summary_for_anchor::<language::Point>(&active_debug_lines.first().unwrap().0.start);
 
         assert_eq!(point.row, 1);
@@ -1679,7 +1679,7 @@ async fn test_active_debug_line_setting(executor: BackgroundExecutor, cx: &mut T
 
         let point = editor
             .snapshot(window, cx)
-            .buffer_snapshot
+            .buffer_snapshot()
             .summary_for_anchor::<language::Point>(&active_debug_lines.first().unwrap().0.start);
 
         assert_eq!(point.row, 2);

crates/debugger_ui/src/tests/stack_frame_list.rs 🔗

@@ -341,8 +341,8 @@ async fn test_select_stack_frame(executor: BackgroundExecutor, cx: &mut TestAppC
                     editor
                         .highlighted_rows::<editor::ActiveDebugLine>()
                         .map(|(range, _)| {
-                            let start = range.start.to_point(&snapshot.buffer_snapshot);
-                            let end = range.end.to_point(&snapshot.buffer_snapshot);
+                            let start = range.start.to_point(&snapshot.buffer_snapshot());
+                            let end = range.end.to_point(&snapshot.buffer_snapshot());
                             start.row..end.row
                         })
                         .collect::<Vec<_>>()
@@ -404,8 +404,8 @@ async fn test_select_stack_frame(executor: BackgroundExecutor, cx: &mut TestAppC
                 editor
                     .highlighted_rows::<editor::ActiveDebugLine>()
                     .map(|(range, _)| {
-                        let start = range.start.to_point(&snapshot.buffer_snapshot);
-                        let end = range.end.to_point(&snapshot.buffer_snapshot);
+                        let start = range.start.to_point(&snapshot.buffer_snapshot());
+                        let end = range.end.to_point(&snapshot.buffer_snapshot());
                         start.row..end.row
                     })
                     .collect::<Vec<_>>()

crates/diagnostics/src/diagnostic_renderer.rs 🔗

@@ -138,7 +138,7 @@ impl editor::DiagnosticRenderer for DiagnosticRenderer {
                 BlockProperties {
                     placement: BlockPlacement::Near(
                         snapshot
-                            .buffer_snapshot
+                            .buffer_snapshot()
                             .anchor_after(block.initial_range.start),
                     ),
                     height: Some(1),
@@ -278,7 +278,7 @@ impl DiagnosticBlock {
             }
         } else if let Some(diagnostic) = editor
             .snapshot(window, cx)
-            .buffer_snapshot
+            .buffer_snapshot()
             .diagnostic_group(buffer_id, group_id)
             .nth(ix)
         {

crates/diagnostics/src/diagnostics_tests.rs 🔗

@@ -863,20 +863,20 @@ async fn test_random_diagnostics_with_inlays(cx: &mut TestAppContext, mut rng: S
             21..=50 => mutated_diagnostics.update_in(cx, |diagnostics, window, cx| {
                 diagnostics.editor.update(cx, |editor, cx| {
                     let snapshot = editor.snapshot(window, cx);
-                    if !snapshot.buffer_snapshot.is_empty() {
-                        let position = rng.random_range(0..snapshot.buffer_snapshot.len());
-                        let position = snapshot.buffer_snapshot.clip_offset(position, Bias::Left);
+                    if !snapshot.buffer_snapshot().is_empty() {
+                        let position = rng.random_range(0..snapshot.buffer_snapshot().len());
+                        let position = snapshot.buffer_snapshot().clip_offset(position, Bias::Left);
                         log::info!(
                             "adding inlay at {position}/{}: {:?}",
-                            snapshot.buffer_snapshot.len(),
-                            snapshot.buffer_snapshot.text(),
+                            snapshot.buffer_snapshot().len(),
+                            snapshot.buffer_snapshot().text(),
                         );
 
                         editor.splice_inlays(
                             &[],
                             vec![Inlay::edit_prediction(
                                 post_inc(&mut next_inlay_id),
-                                snapshot.buffer_snapshot.anchor_before(position),
+                                snapshot.buffer_snapshot().anchor_before(position),
                                 Rope::from_iter(["Test inlay ", "next_inlay_id"]),
                             )],
                             cx,

crates/editor/src/display_map.rs 🔗

@@ -170,20 +170,15 @@ impl DisplayMap {
         let buffer_snapshot = self.buffer.read(cx).snapshot(cx);
         let edits = self.buffer_subscription.consume().into_inner();
         let (inlay_snapshot, edits) = self.inlay_map.sync(buffer_snapshot, edits);
-        let (fold_snapshot, edits) = self.fold_map.read(inlay_snapshot.clone(), edits);
+        let (fold_snapshot, edits) = self.fold_map.read(inlay_snapshot, edits);
         let tab_size = Self::tab_size(&self.buffer, cx);
-        let (tab_snapshot, edits) = self.tab_map.sync(fold_snapshot.clone(), edits, tab_size);
+        let (tab_snapshot, edits) = self.tab_map.sync(fold_snapshot, edits, tab_size);
         let (wrap_snapshot, edits) = self
             .wrap_map
-            .update(cx, |map, cx| map.sync(tab_snapshot.clone(), edits, cx));
-        let block_snapshot = self.block_map.read(wrap_snapshot.clone(), edits).snapshot;
+            .update(cx, |map, cx| map.sync(tab_snapshot, edits, cx));
+        let block_snapshot = self.block_map.read(wrap_snapshot, edits).snapshot;
 
         DisplaySnapshot {
-            buffer_snapshot: self.buffer.read(cx).snapshot(cx),
-            fold_snapshot,
-            inlay_snapshot,
-            tab_snapshot,
-            wrap_snapshot,
             block_snapshot,
             diagnostics_max_severity: self.diagnostics_max_severity,
             crease_snapshot: self.crease_map.snapshot(),
@@ -198,10 +193,10 @@ impl DisplayMap {
     pub fn set_state(&mut self, other: &DisplaySnapshot, cx: &mut Context<Self>) {
         self.fold(
             other
-                .folds_in_range(0..other.buffer_snapshot.len())
+                .folds_in_range(0..other.buffer_snapshot().len())
                 .map(|fold| {
                     Crease::simple(
-                        fold.range.to_offset(&other.buffer_snapshot),
+                        fold.range.to_offset(other.buffer_snapshot()),
                         fold.placeholder.clone(),
                     )
                 })
@@ -762,12 +757,7 @@ impl<'a> HighlightedChunk<'a> {
 
 #[derive(Clone)]
 pub struct DisplaySnapshot {
-    pub buffer_snapshot: MultiBufferSnapshot,
-    pub fold_snapshot: FoldSnapshot,
     pub crease_snapshot: CreaseSnapshot,
-    inlay_snapshot: InlaySnapshot,
-    tab_snapshot: TabSnapshot,
-    wrap_snapshot: WrapSnapshot,
     block_snapshot: BlockSnapshot,
     text_highlights: TextHighlights,
     inlay_highlights: InlayHighlights,
@@ -776,15 +766,44 @@ pub struct DisplaySnapshot {
     diagnostics_max_severity: DiagnosticSeverity,
     pub(crate) fold_placeholder: FoldPlaceholder,
 }
-
 impl DisplaySnapshot {
+    pub fn wrap_snapshot(&self) -> &WrapSnapshot {
+        &self.block_snapshot.wrap_snapshot
+    }
+    pub fn tab_snapshot(&self) -> &TabSnapshot {
+        &self.block_snapshot.wrap_snapshot.tab_snapshot
+    }
+
+    pub fn fold_snapshot(&self) -> &FoldSnapshot {
+        &self.block_snapshot.wrap_snapshot.tab_snapshot.fold_snapshot
+    }
+
+    pub fn inlay_snapshot(&self) -> &InlaySnapshot {
+        &self
+            .block_snapshot
+            .wrap_snapshot
+            .tab_snapshot
+            .fold_snapshot
+            .inlay_snapshot
+    }
+
+    pub fn buffer_snapshot(&self) -> &MultiBufferSnapshot {
+        &self
+            .block_snapshot
+            .wrap_snapshot
+            .tab_snapshot
+            .fold_snapshot
+            .inlay_snapshot
+            .buffer
+    }
+
     #[cfg(test)]
     pub fn fold_count(&self) -> usize {
-        self.fold_snapshot.fold_count()
+        self.fold_snapshot().fold_count()
     }
 
     pub fn is_empty(&self) -> bool {
-        self.buffer_snapshot.len() == 0
+        self.buffer_snapshot().len() == 0
     }
 
     pub fn row_infos(&self, start_row: DisplayRow) -> impl Iterator<Item = RowInfo> + '_ {
@@ -792,16 +811,16 @@ impl DisplaySnapshot {
     }
 
     pub fn widest_line_number(&self) -> u32 {
-        self.buffer_snapshot.widest_line_number()
+        self.buffer_snapshot().widest_line_number()
     }
 
     pub fn prev_line_boundary(&self, mut point: MultiBufferPoint) -> (Point, DisplayPoint) {
         loop {
-            let mut inlay_point = self.inlay_snapshot.to_inlay_point(point);
-            let mut fold_point = self.fold_snapshot.to_fold_point(inlay_point, Bias::Left);
+            let mut inlay_point = self.inlay_snapshot().to_inlay_point(point);
+            let mut fold_point = self.fold_snapshot().to_fold_point(inlay_point, Bias::Left);
             fold_point.0.column = 0;
-            inlay_point = fold_point.to_inlay_point(&self.fold_snapshot);
-            point = self.inlay_snapshot.to_buffer_point(inlay_point);
+            inlay_point = fold_point.to_inlay_point(self.fold_snapshot());
+            point = self.inlay_snapshot().to_buffer_point(inlay_point);
 
             let mut display_point = self.point_to_display_point(point, Bias::Left);
             *display_point.column_mut() = 0;
@@ -819,11 +838,11 @@ impl DisplaySnapshot {
     ) -> (MultiBufferPoint, DisplayPoint) {
         let original_point = point;
         loop {
-            let mut inlay_point = self.inlay_snapshot.to_inlay_point(point);
-            let mut fold_point = self.fold_snapshot.to_fold_point(inlay_point, Bias::Right);
-            fold_point.0.column = self.fold_snapshot.line_len(fold_point.row());
-            inlay_point = fold_point.to_inlay_point(&self.fold_snapshot);
-            point = self.inlay_snapshot.to_buffer_point(inlay_point);
+            let mut inlay_point = self.inlay_snapshot().to_inlay_point(point);
+            let mut fold_point = self.fold_snapshot().to_fold_point(inlay_point, Bias::Right);
+            fold_point.0.column = self.fold_snapshot().line_len(fold_point.row());
+            inlay_point = fold_point.to_inlay_point(self.fold_snapshot());
+            point = self.inlay_snapshot().to_buffer_point(inlay_point);
 
             let mut display_point = self.point_to_display_point(point, Bias::Right);
             *display_point.column_mut() = self.line_len(display_point.row());
@@ -841,7 +860,8 @@ impl DisplaySnapshot {
         let new_end = if range.end.column > 0 {
             MultiBufferPoint::new(
                 range.end.row,
-                self.buffer_snapshot.line_len(MultiBufferRow(range.end.row)),
+                self.buffer_snapshot()
+                    .line_len(MultiBufferRow(range.end.row)),
             )
         } else {
             range.end
@@ -851,52 +871,52 @@ impl DisplaySnapshot {
     }
 
     pub fn point_to_display_point(&self, point: MultiBufferPoint, bias: Bias) -> DisplayPoint {
-        let inlay_point = self.inlay_snapshot.to_inlay_point(point);
-        let fold_point = self.fold_snapshot.to_fold_point(inlay_point, bias);
-        let tab_point = self.tab_snapshot.to_tab_point(fold_point);
-        let wrap_point = self.wrap_snapshot.tab_point_to_wrap_point(tab_point);
+        let inlay_point = self.inlay_snapshot().to_inlay_point(point);
+        let fold_point = self.fold_snapshot().to_fold_point(inlay_point, bias);
+        let tab_point = self.tab_snapshot().to_tab_point(fold_point);
+        let wrap_point = self.wrap_snapshot().tab_point_to_wrap_point(tab_point);
         let block_point = self.block_snapshot.to_block_point(wrap_point);
         DisplayPoint(block_point)
     }
 
     pub fn display_point_to_point(&self, point: DisplayPoint, bias: Bias) -> Point {
-        self.inlay_snapshot
+        self.inlay_snapshot()
             .to_buffer_point(self.display_point_to_inlay_point(point, bias))
     }
 
     pub fn display_point_to_inlay_offset(&self, point: DisplayPoint, bias: Bias) -> InlayOffset {
-        self.inlay_snapshot
+        self.inlay_snapshot()
             .to_offset(self.display_point_to_inlay_point(point, bias))
     }
 
     pub fn anchor_to_inlay_offset(&self, anchor: Anchor) -> InlayOffset {
-        self.inlay_snapshot
-            .to_inlay_offset(anchor.to_offset(&self.buffer_snapshot))
+        self.inlay_snapshot()
+            .to_inlay_offset(anchor.to_offset(self.buffer_snapshot()))
     }
 
     pub fn display_point_to_anchor(&self, point: DisplayPoint, bias: Bias) -> Anchor {
-        self.buffer_snapshot
+        self.buffer_snapshot()
             .anchor_at(point.to_offset(self, bias), bias)
     }
 
     fn display_point_to_inlay_point(&self, point: DisplayPoint, bias: Bias) -> InlayPoint {
         let block_point = point.0;
         let wrap_point = self.block_snapshot.to_wrap_point(block_point, bias);
-        let tab_point = self.wrap_snapshot.to_tab_point(wrap_point);
-        let fold_point = self.tab_snapshot.to_fold_point(tab_point, bias).0;
-        fold_point.to_inlay_point(&self.fold_snapshot)
+        let tab_point = self.wrap_snapshot().to_tab_point(wrap_point);
+        let fold_point = self.tab_snapshot().to_fold_point(tab_point, bias).0;
+        fold_point.to_inlay_point(self.fold_snapshot())
     }
 
     pub fn display_point_to_fold_point(&self, point: DisplayPoint, bias: Bias) -> FoldPoint {
         let block_point = point.0;
         let wrap_point = self.block_snapshot.to_wrap_point(block_point, bias);
-        let tab_point = self.wrap_snapshot.to_tab_point(wrap_point);
-        self.tab_snapshot.to_fold_point(tab_point, bias).0
+        let tab_point = self.wrap_snapshot().to_tab_point(wrap_point);
+        self.tab_snapshot().to_fold_point(tab_point, bias).0
     }
 
     pub fn fold_point_to_display_point(&self, fold_point: FoldPoint) -> DisplayPoint {
-        let tab_point = self.tab_snapshot.to_tab_point(fold_point);
-        let wrap_point = self.wrap_snapshot.tab_point_to_wrap_point(tab_point);
+        let tab_point = self.tab_snapshot().to_tab_point(fold_point);
+        let wrap_point = self.wrap_snapshot().tab_point_to_wrap_point(tab_point);
         let block_point = self.block_snapshot.to_block_point(wrap_point);
         DisplayPoint(block_point)
     }
@@ -1118,7 +1138,7 @@ impl DisplaySnapshot {
     }
 
     pub fn buffer_chars_at(&self, mut offset: usize) -> impl Iterator<Item = (char, usize)> + '_ {
-        self.buffer_snapshot.chars_at(offset).map(move |ch| {
+        self.buffer_snapshot().chars_at(offset).map(move |ch| {
             let ret = (ch, offset);
             offset += ch.len_utf8();
             ret
@@ -1129,7 +1149,7 @@ impl DisplaySnapshot {
         &self,
         mut offset: usize,
     ) -> impl Iterator<Item = (char, usize)> + '_ {
-        self.buffer_snapshot
+        self.buffer_snapshot()
             .reversed_chars_at(offset)
             .map(move |ch| {
                 offset -= ch.len_utf8();
@@ -1152,11 +1172,11 @@ impl DisplaySnapshot {
     pub fn clip_at_line_end(&self, display_point: DisplayPoint) -> DisplayPoint {
         let mut point = self.display_point_to_point(display_point, Bias::Left);
 
-        if point.column != self.buffer_snapshot.line_len(MultiBufferRow(point.row)) {
+        if point.column != self.buffer_snapshot().line_len(MultiBufferRow(point.row)) {
             return display_point;
         }
         point.column = point.column.saturating_sub(1);
-        point = self.buffer_snapshot.clip_point(point, Bias::Left);
+        point = self.buffer_snapshot().clip_point(point, Bias::Left);
         self.point_to_display_point(point, Bias::Left)
     }
 
@@ -1164,7 +1184,7 @@ impl DisplaySnapshot {
     where
         T: ToOffset,
     {
-        self.fold_snapshot.folds_in_range(range)
+        self.fold_snapshot().folds_in_range(range)
     }
 
     pub fn blocks_in_range(
@@ -1185,12 +1205,12 @@ impl DisplaySnapshot {
     }
 
     pub fn intersects_fold<T: ToOffset>(&self, offset: T) -> bool {
-        self.fold_snapshot.intersects_fold(offset)
+        self.fold_snapshot().intersects_fold(offset)
     }
 
     pub fn is_line_folded(&self, buffer_row: MultiBufferRow) -> bool {
         self.block_snapshot.is_line_replaced(buffer_row)
-            || self.fold_snapshot.is_line_folded(buffer_row)
+            || self.fold_snapshot().is_line_folded(buffer_row)
     }
 
     pub fn is_block_line(&self, display_row: DisplayRow) -> bool {
@@ -1207,7 +1227,7 @@ impl DisplaySnapshot {
             .block_snapshot
             .to_wrap_point(BlockPoint::new(display_row.0, 0), Bias::Left)
             .row();
-        self.wrap_snapshot.soft_wrap_indent(wrap_row)
+        self.wrap_snapshot().soft_wrap_indent(wrap_row)
     }
 
     pub fn text(&self) -> String {
@@ -1228,7 +1248,7 @@ impl DisplaySnapshot {
     }
 
     pub fn line_indent_for_buffer_row(&self, buffer_row: MultiBufferRow) -> LineIndent {
-        self.buffer_snapshot.line_indent_for_row(buffer_row)
+        self.buffer_snapshot().line_indent_for_row(buffer_row)
     }
 
     pub fn line_len(&self, row: DisplayRow) -> u32 {
@@ -1246,7 +1266,7 @@ impl DisplaySnapshot {
     }
 
     pub fn starts_indent(&self, buffer_row: MultiBufferRow) -> bool {
-        let max_row = self.buffer_snapshot.max_row();
+        let max_row = self.buffer_snapshot().max_row();
         if buffer_row >= max_row {
             return false;
         }
@@ -1271,10 +1291,11 @@ impl DisplaySnapshot {
     }
 
     pub fn crease_for_buffer_row(&self, buffer_row: MultiBufferRow) -> Option<Crease<Point>> {
-        let start = MultiBufferPoint::new(buffer_row.0, self.buffer_snapshot.line_len(buffer_row));
+        let start =
+            MultiBufferPoint::new(buffer_row.0, self.buffer_snapshot().line_len(buffer_row));
         if let Some(crease) = self
             .crease_snapshot
-            .query_row(buffer_row, &self.buffer_snapshot)
+            .query_row(buffer_row, self.buffer_snapshot())
         {
             match crease {
                 Crease::Inline {
@@ -1284,7 +1305,7 @@ impl DisplaySnapshot {
                     render_trailer,
                     metadata,
                 } => Some(Crease::Inline {
-                    range: range.to_point(&self.buffer_snapshot),
+                    range: range.to_point(self.buffer_snapshot()),
                     placeholder: placeholder.clone(),
                     render_toggle: render_toggle.clone(),
                     render_trailer: render_trailer.clone(),
@@ -1298,7 +1319,7 @@ impl DisplaySnapshot {
                     block_priority,
                     render_toggle,
                 } => Some(Crease::Block {
-                    range: range.to_point(&self.buffer_snapshot),
+                    range: range.to_point(self.buffer_snapshot()),
                     block_height: *block_height,
                     block_style: *block_style,
                     render_block: render_block.clone(),
@@ -1310,7 +1331,7 @@ impl DisplaySnapshot {
             && !self.is_line_folded(MultiBufferRow(start.row))
         {
             let start_line_indent = self.line_indent_for_buffer_row(buffer_row);
-            let max_point = self.buffer_snapshot.max_point();
+            let max_point = self.buffer_snapshot().max_point();
             let mut end = None;
 
             for row in (buffer_row.0 + 1)..=max_point.row {
@@ -1321,7 +1342,7 @@ impl DisplaySnapshot {
                     let prev_row = row - 1;
                     end = Some(Point::new(
                         prev_row,
-                        self.buffer_snapshot.line_len(MultiBufferRow(prev_row)),
+                        self.buffer_snapshot().line_len(MultiBufferRow(prev_row)),
                     ));
                     break;
                 }
@@ -1330,7 +1351,7 @@ impl DisplaySnapshot {
             let mut row_before_line_breaks = end.unwrap_or(max_point);
             while row_before_line_breaks.row > start.row
                 && self
-                    .buffer_snapshot
+                    .buffer_snapshot()
                     .is_line_blank(MultiBufferRow(row_before_line_breaks.row))
             {
                 row_before_line_breaks.row -= 1;
@@ -1338,7 +1359,7 @@ impl DisplaySnapshot {
 
             row_before_line_breaks = Point::new(
                 row_before_line_breaks.row,
-                self.buffer_snapshot
+                self.buffer_snapshot()
                     .line_len(MultiBufferRow(row_before_line_breaks.row)),
             );
 
@@ -1482,23 +1503,23 @@ impl DisplayPoint {
 
     pub fn to_offset(self, map: &DisplaySnapshot, bias: Bias) -> usize {
         let wrap_point = map.block_snapshot.to_wrap_point(self.0, bias);
-        let tab_point = map.wrap_snapshot.to_tab_point(wrap_point);
-        let fold_point = map.tab_snapshot.to_fold_point(tab_point, bias).0;
-        let inlay_point = fold_point.to_inlay_point(&map.fold_snapshot);
-        map.inlay_snapshot
-            .to_buffer_offset(map.inlay_snapshot.to_offset(inlay_point))
+        let tab_point = map.wrap_snapshot().to_tab_point(wrap_point);
+        let fold_point = map.tab_snapshot().to_fold_point(tab_point, bias).0;
+        let inlay_point = fold_point.to_inlay_point(map.fold_snapshot());
+        map.inlay_snapshot()
+            .to_buffer_offset(map.inlay_snapshot().to_offset(inlay_point))
     }
 }
 
 impl ToDisplayPoint for usize {
     fn to_display_point(&self, map: &DisplaySnapshot) -> DisplayPoint {
-        map.point_to_display_point(self.to_point(&map.buffer_snapshot), Bias::Left)
+        map.point_to_display_point(self.to_point(map.buffer_snapshot()), Bias::Left)
     }
 }
 
 impl ToDisplayPoint for OffsetUtf16 {
     fn to_display_point(&self, map: &DisplaySnapshot) -> DisplayPoint {
-        self.to_offset(&map.buffer_snapshot).to_display_point(map)
+        self.to_offset(map.buffer_snapshot()).to_display_point(map)
     }
 }
 
@@ -1510,7 +1531,7 @@ impl ToDisplayPoint for Point {
 
 impl ToDisplayPoint for Anchor {
     fn to_display_point(&self, map: &DisplaySnapshot) -> DisplayPoint {
-        self.to_point(&map.buffer_snapshot).to_display_point(map)
+        self.to_point(map.buffer_snapshot()).to_display_point(map)
     }
 }
 
@@ -1599,10 +1620,10 @@ pub mod tests {
         let mut blocks = Vec::new();
 
         let snapshot = map.update(cx, |map, cx| map.snapshot(cx));
-        log::info!("buffer text: {:?}", snapshot.buffer_snapshot.text());
-        log::info!("fold text: {:?}", snapshot.fold_snapshot.text());
-        log::info!("tab text: {:?}", snapshot.tab_snapshot.text());
-        log::info!("wrap text: {:?}", snapshot.wrap_snapshot.text());
+        log::info!("buffer text: {:?}", snapshot.buffer_snapshot().text());
+        log::info!("fold text: {:?}", snapshot.fold_snapshot().text());
+        log::info!("tab text: {:?}", snapshot.tab_snapshot().text());
+        log::info!("wrap text: {:?}", snapshot.wrap_snapshot().text());
         log::info!("block text: {:?}", snapshot.block_snapshot.text());
         log::info!("display text: {:?}", snapshot.text());
 
@@ -1634,7 +1655,8 @@ pub mod tests {
                 30..=44 => {
                     map.update(cx, |map, cx| {
                         if rng.random() || blocks.is_empty() {
-                            let buffer = map.snapshot(cx).buffer_snapshot;
+                            let snapshot = map.snapshot(cx);
+                            let buffer = snapshot.buffer_snapshot();
                             let block_properties = (0..rng.random_range(1..=1))
                                 .map(|_| {
                                     let position = buffer.anchor_after(buffer.clip_offset(
@@ -1715,15 +1737,15 @@ pub mod tests {
 
             let snapshot = map.update(cx, |map, cx| map.snapshot(cx));
             fold_count = snapshot.fold_count();
-            log::info!("buffer text: {:?}", snapshot.buffer_snapshot.text());
-            log::info!("fold text: {:?}", snapshot.fold_snapshot.text());
-            log::info!("tab text: {:?}", snapshot.tab_snapshot.text());
-            log::info!("wrap text: {:?}", snapshot.wrap_snapshot.text());
+            log::info!("buffer text: {:?}", snapshot.buffer_snapshot().text());
+            log::info!("fold text: {:?}", snapshot.fold_snapshot().text());
+            log::info!("tab text: {:?}", snapshot.tab_snapshot().text());
+            log::info!("wrap text: {:?}", snapshot.wrap_snapshot().text());
             log::info!("block text: {:?}", snapshot.block_snapshot.text());
             log::info!("display text: {:?}", snapshot.text());
 
             // Line boundaries
-            let buffer = &snapshot.buffer_snapshot;
+            let buffer = snapshot.buffer_snapshot();
             for _ in 0..5 {
                 let row = rng.random_range(0..=buffer.max_point().row);
                 let column = rng.random_range(0..=buffer.line_len(MultiBufferRow(row)));
@@ -1907,7 +1929,7 @@ pub mod tests {
                 )
             );
 
-            let ix = snapshot.buffer_snapshot.text().find("seven").unwrap();
+            let ix = snapshot.buffer_snapshot().text().find("seven").unwrap();
             buffer.update(cx, |buffer, cx| {
                 buffer.edit([(ix..ix, "and ")], None, cx);
             });

crates/editor/src/display_map/block_map.rs 🔗

@@ -33,8 +33,8 @@ const BULLETS: &[u8; u128::BITS as usize] = &[b'*'; _];
 ///
 /// See the [`display_map` module documentation](crate::display_map) for more information.
 pub struct BlockMap {
+    pub(super) wrap_snapshot: RefCell<WrapSnapshot>,
     next_block_id: AtomicUsize,
-    wrap_snapshot: RefCell<WrapSnapshot>,
     custom_blocks: Vec<Arc<CustomBlock>>,
     custom_blocks_by_id: TreeMap<CustomBlockId, Arc<CustomBlock>>,
     transforms: RefCell<SumTree<Transform>>,
@@ -53,7 +53,7 @@ pub struct BlockMapWriter<'a>(&'a mut BlockMap);
 
 #[derive(Clone)]
 pub struct BlockSnapshot {
-    wrap_snapshot: WrapSnapshot,
+    pub(super) wrap_snapshot: WrapSnapshot,
     transforms: SumTree<Transform>,
     custom_blocks_by_id: TreeMap<CustomBlockId, Arc<CustomBlock>>,
     pub(super) buffer_header_height: u32,

crates/editor/src/display_map/fold_map.rs 🔗

@@ -624,10 +624,10 @@ impl FoldMap {
 
 #[derive(Clone)]
 pub struct FoldSnapshot {
+    pub inlay_snapshot: InlaySnapshot,
     transforms: SumTree<Transform>,
     folds: SumTree<Fold>,
     fold_metadata_by_id: TreeMap<FoldId, FoldMetadata>,
-    pub inlay_snapshot: InlaySnapshot,
     pub version: usize,
 }
 

crates/editor/src/display_map/wrap_map.rs 🔗

@@ -30,7 +30,7 @@ pub struct WrapMap {
 
 #[derive(Clone)]
 pub struct WrapSnapshot {
-    tab_snapshot: TabSnapshot,
+    pub(super) tab_snapshot: TabSnapshot,
     transforms: SumTree<Transform>,
     interpolated: bool,
 }

crates/editor/src/editor.rs 🔗

@@ -2297,7 +2297,7 @@ impl Editor {
                         let snapshot = editor.snapshot(window, cx);
                         editor.update_restoration_data(cx, move |data| {
                             data.scroll_position = (
-                                new_anchor.top_row(&snapshot.buffer_snapshot),
+                                new_anchor.top_row(snapshot.buffer_snapshot()),
                                 new_anchor.offset,
                             );
                         });
@@ -3083,7 +3083,7 @@ impl Editor {
         let display_map = self
             .display_map
             .update(cx, |display_map, cx| display_map.snapshot(cx));
-        let buffer = &display_map.buffer_snapshot;
+        let buffer = display_map.buffer_snapshot();
         if self.selections.count() == 1 {
             self.add_selections_state = None;
         }
@@ -3247,22 +3247,23 @@ impl Editor {
             return;
         }
 
-        let Some(singleton) = self.buffer().read(cx).as_singleton() else {
+        if !self.buffer().read(cx).is_singleton() {
             return;
-        };
-
-        let snapshot = singleton.read(cx).snapshot();
-        let inmemory_folds = self.display_map.update(cx, |display_map, cx| {
-            let display_snapshot = display_map.snapshot(cx);
+        }
 
-            display_snapshot
-                .folds_in_range(0..display_snapshot.buffer_snapshot.len())
-                .map(|fold| {
-                    fold.range.start.text_anchor.to_point(&snapshot)
-                        ..fold.range.end.text_anchor.to_point(&snapshot)
-                })
-                .collect()
-        });
+        let display_snapshot = self
+            .display_map
+            .update(cx, |display_map, cx| display_map.snapshot(cx));
+        let Some((.., snapshot)) = display_snapshot.buffer_snapshot().as_singleton() else {
+            return;
+        };
+        let inmemory_folds = display_snapshot
+            .folds_in_range(0..display_snapshot.buffer_snapshot().len())
+            .map(|fold| {
+                fold.range.start.text_anchor.to_point(&snapshot)
+                    ..fold.range.end.text_anchor.to_point(&snapshot)
+            })
+            .collect();
         self.update_restoration_data(cx, |data| {
             data.folds = inmemory_folds;
         });
@@ -3272,18 +3273,15 @@ impl Editor {
         };
         let background_executor = cx.background_executor().clone();
         let editor_id = cx.entity().entity_id().as_u64() as ItemId;
-        let db_folds = self.display_map.update(cx, |display_map, cx| {
-            display_map
-                .snapshot(cx)
-                .folds_in_range(0..snapshot.len())
-                .map(|fold| {
-                    (
-                        fold.range.start.text_anchor.to_offset(&snapshot),
-                        fold.range.end.text_anchor.to_offset(&snapshot),
-                    )
-                })
-                .collect()
-        });
+        let db_folds = display_snapshot
+            .folds_in_range(0..display_snapshot.buffer_snapshot().len())
+            .map(|fold| {
+                (
+                    fold.range.start.text_anchor.to_offset(&snapshot),
+                    fold.range.end.text_anchor.to_offset(&snapshot),
+                )
+            })
+            .collect();
         self.serialize_folds = cx.background_spawn(async move {
             background_executor.timer(SERIALIZATION_THROTTLE_TIME).await;
             DB.save_editor_folds(editor_id, workspace_id, db_folds)
@@ -3516,7 +3514,7 @@ impl Editor {
         self.begin_selection(position, false, click_count, window, cx);
 
         let position = position.to_offset(&display_map, Bias::Left);
-        let tail_anchor = display_map.buffer_snapshot.anchor_before(tail);
+        let tail_anchor = display_map.buffer_snapshot().anchor_before(tail);
 
         let mut pending_selection = self
             .selections
@@ -3561,7 +3559,7 @@ impl Editor {
         }
 
         let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
-        let buffer = &display_map.buffer_snapshot;
+        let buffer = display_map.buffer_snapshot();
         let position = display_map.clip_point(position, Bias::Left);
 
         let start;
@@ -3669,7 +3667,7 @@ impl Editor {
 
         if reset {
             let pointer_position = display_map
-                .buffer_snapshot
+                .buffer_snapshot()
                 .anchor_before(position.to_point(&display_map));
 
             self.change_selections(
@@ -3687,7 +3685,7 @@ impl Editor {
         };
 
         let tail = self.selections.newest::<Point>(cx).tail();
-        let selection_anchor = display_map.buffer_snapshot.anchor_before(tail);
+        let selection_anchor = display_map.buffer_snapshot().anchor_before(tail);
         self.columnar_selection_state = match mode {
             ColumnarMode::FromMouse => Some(ColumnarSelectionState::FromMouse {
                 selection_tail: selection_anchor,
@@ -3724,7 +3722,7 @@ impl Editor {
         if self.columnar_selection_state.is_some() {
             self.select_columns(position, goal_column, &display_map, window, cx);
         } else if let Some(mut pending) = self.selections.pending_anchor().cloned() {
-            let buffer = &display_map.buffer_snapshot;
+            let buffer = display_map.buffer_snapshot();
             let head;
             let tail;
             let mode = self.selections.pending_mode().unwrap();
@@ -3760,7 +3758,7 @@ impl Editor {
                     }
                 }
                 SelectMode::Line(original_range) => {
-                    let original_range = original_range.to_point(&display_map.buffer_snapshot);
+                    let original_range = original_range.to_point(display_map.buffer_snapshot());
 
                     let position = display_map
                         .clip_point(position, Bias::Left)
@@ -4339,15 +4337,19 @@ impl Editor {
 
             let mut i = 0;
             for (position, delta, selection_id, pair) in new_autoclose_regions {
-                let position = position.to_offset(&map.buffer_snapshot) + delta;
-                let start = map.buffer_snapshot.anchor_before(position);
-                let end = map.buffer_snapshot.anchor_after(position);
+                let position = position.to_offset(map.buffer_snapshot()) + delta;
+                let start = map.buffer_snapshot().anchor_before(position);
+                let end = map.buffer_snapshot().anchor_after(position);
                 while let Some(existing_state) = this.autoclose_regions.get(i) {
-                    match existing_state.range.start.cmp(&start, &map.buffer_snapshot) {
+                    match existing_state
+                        .range
+                        .start
+                        .cmp(&start, map.buffer_snapshot())
+                    {
                         Ordering::Less => i += 1,
                         Ordering::Greater => break,
                         Ordering::Equal => {
-                            match end.cmp(&existing_state.range.end, &map.buffer_snapshot) {
+                            match end.cmp(&existing_state.range.end, map.buffer_snapshot()) {
                                 Ordering::Less => i += 1,
                                 Ordering::Equal => break,
                                 Ordering::Greater => break,
@@ -6158,7 +6160,7 @@ impl Editor {
             _ => self.selections.newest::<Point>(cx).head(),
         };
         let Some((buffer, buffer_row)) = snapshot
-            .buffer_snapshot
+            .buffer_snapshot()
             .buffer_line_for_row(MultiBufferRow(multibuffer_point.row))
             .and_then(|(buffer_snapshot, range)| {
                 self.buffer()
@@ -6206,7 +6208,7 @@ impl Editor {
                                 .zip(task_context.clone())
                                 .map(|(tasks, task_context)| ResolvedTasks {
                                     templates: tasks.resolve(&task_context).collect(),
-                                    position: snapshot.buffer_snapshot.anchor_before(Point::new(
+                                    position: snapshot.buffer_snapshot().anchor_before(Point::new(
                                         multibuffer_point.row,
                                         tasks.column,
                                     )),
@@ -6688,7 +6690,7 @@ impl Editor {
     pub fn blame_hover(&mut self, _: &BlameHover, window: &mut Window, cx: &mut Context<Self>) {
         let snapshot = self.snapshot(window, cx);
         let cursor = self.selections.newest::<Point>(cx).head();
-        let Some((buffer, point, _)) = snapshot.buffer_snapshot.point_to_buffer_point(cursor)
+        let Some((buffer, point, _)) = snapshot.buffer_snapshot().point_to_buffer_point(cursor)
         else {
             return;
         };
@@ -7009,7 +7011,7 @@ impl Editor {
             return;
         }
         let snapshot = self.snapshot(window, cx);
-        if snapshot.buffer_snapshot.max_point().row == 0 {
+        if snapshot.buffer_snapshot().max_point().row == 0 {
             return;
         }
         let task = cx.background_spawn(async move {
@@ -7018,8 +7020,8 @@ impl Editor {
                 .filter_map(|(c, i)| {
                     if c == '\n' {
                         Some(
-                            snapshot.buffer_snapshot.anchor_after(i)
-                                ..snapshot.buffer_snapshot.anchor_before(i + 1),
+                            snapshot.buffer_snapshot().anchor_after(i)
+                                ..snapshot.buffer_snapshot().anchor_before(i + 1),
                         )
                     } else {
                         None
@@ -7027,7 +7029,7 @@ impl Editor {
                 })
                 .collect::<Vec<_>>();
             let existing_newlines = snapshot
-                .folds_in_range(0..snapshot.buffer_snapshot.len())
+                .folds_in_range(0..snapshot.buffer_snapshot().len())
                 .filter_map(|fold| {
                     if fold.placeholder.type_tag == Some(type_id) {
                         Some(fold.range.start..fold.range.end)
@@ -8109,7 +8111,7 @@ impl Editor {
 
         let snapshot = self.snapshot(window, cx);
 
-        let multi_buffer_snapshot = &snapshot.display_snapshot.buffer_snapshot;
+        let multi_buffer_snapshot = snapshot.display_snapshot.buffer_snapshot();
         let Some(project) = self.project() else {
             return breakpoint_display_points;
         };
@@ -10011,7 +10013,7 @@ impl Editor {
                         movement::left(&display_map, old_head.to_display_point(&display_map))
                             .to_point(&display_map);
                     if let Some((buffer, line_buffer_range)) = display_map
-                        .buffer_snapshot
+                        .buffer_snapshot()
                         .buffer_line_for_row(MultiBufferRow(old_head.row))
                     {
                         let indent_size = buffer.indent_size_for_line(line_buffer_range.start.row);
@@ -10456,7 +10458,7 @@ impl Editor {
                 }
             }
 
-            let buffer = &display_map.buffer_snapshot;
+            let buffer = display_map.buffer_snapshot();
             let mut edit_start = Point::new(rows.start.0, 0).to_offset(buffer);
             let edit_end = if buffer.max_point().row >= rows.end.0 {
                 // If there's a line after the range, delete the \n from the end of the row range
@@ -10891,7 +10893,7 @@ impl Editor {
         cx: &mut Context<Self>,
     ) -> Option<(Anchor, Breakpoint)> {
         let snapshot = self.snapshot(window, cx);
-        let breakpoint_position = snapshot.buffer_snapshot.anchor_before(Point::new(row, 0));
+        let breakpoint_position = snapshot.buffer_snapshot().anchor_before(Point::new(row, 0));
 
         self.breakpoint_at_anchor(breakpoint_position, &snapshot, cx)
     }
@@ -10914,9 +10916,9 @@ impl Editor {
             .summary_for_anchor::<text::PointUtf16>(&breakpoint_position.text_anchor)
             .row;
 
-        let line_len = snapshot.buffer_snapshot.line_len(MultiBufferRow(row));
+        let line_len = snapshot.buffer_snapshot().line_len(MultiBufferRow(row));
         let anchor_end = snapshot
-            .buffer_snapshot
+            .buffer_snapshot()
             .anchor_after(Point::new(row, line_len));
 
         self.breakpoint_store
@@ -10937,7 +10939,7 @@ impl Editor {
 
                         if breakpoint_row == row {
                             snapshot
-                                .buffer_snapshot
+                                .buffer_snapshot()
                                 .anchor_in_excerpt(enclosing_excerpt, bp.position)
                                 .map(|position| (position, bp.bp.clone()))
                         } else {
@@ -10982,7 +10984,7 @@ impl Editor {
             .disjoint_anchors_arc()
             .iter()
             .map(|selection| {
-                let cursor_position: Point = selection.head().to_point(&snapshot.buffer_snapshot);
+                let cursor_position: Point = selection.head().to_point(&snapshot.buffer_snapshot());
 
                 let breakpoint_position = self
                     .breakpoint_at_row(cursor_position.row, window, cx)
@@ -10990,7 +10992,7 @@ impl Editor {
                     .unwrap_or_else(|| {
                         snapshot
                             .display_snapshot
-                            .buffer_snapshot
+                            .buffer_snapshot()
                             .anchor_after(Point::new(cursor_position.row, 0))
                     });
 
@@ -11619,7 +11621,7 @@ impl Editor {
         cx: &mut Context<Self>,
     ) {
         let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
-        let buffer = &display_map.buffer_snapshot;
+        let buffer = display_map.buffer_snapshot();
         let mut edits = Vec::new();
         let insert_point = display_map
             .clip_point(target, Bias::Left)
@@ -11658,7 +11660,7 @@ impl Editor {
         self.hide_mouse_cursor(HideMouseCursorOrigin::TypingAction, cx);
 
         let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
-        let buffer = &display_map.buffer_snapshot;
+        let buffer = display_map.buffer_snapshot();
         let selections = self.selections.all::<Point>(cx);
 
         let mut edits = Vec::new();
@@ -11960,7 +11962,7 @@ impl Editor {
                     let mut transpose_offset = head.to_offset(display_map, Bias::Right);
                     if head.column() == display_map.line_len(head.row()) {
                         transpose_offset = display_map
-                            .buffer_snapshot
+                            .buffer_snapshot()
                             .clip_offset(transpose_offset.saturating_sub(1), Bias::Left);
                     }
 
@@ -11978,14 +11980,16 @@ impl Editor {
                     selection.collapse_to(head, goal);
 
                     let transpose_start = display_map
-                        .buffer_snapshot
+                        .buffer_snapshot()
                         .clip_offset(transpose_offset.saturating_sub(1), Bias::Left);
                     if edits.last().is_none_or(|e| e.0.end <= transpose_start) {
                         let transpose_end = display_map
-                            .buffer_snapshot
+                            .buffer_snapshot()
                             .clip_offset(transpose_offset + 1, Bias::Right);
-                        if let Some(ch) =
-                            display_map.buffer_snapshot.chars_at(transpose_start).next()
+                        if let Some(ch) = display_map
+                            .buffer_snapshot()
+                            .chars_at(transpose_start)
+                            .next()
                         {
                             edits.push((transpose_start..transpose_offset, String::new()));
                             edits.push((transpose_end..transpose_end, ch.to_string()));
@@ -14093,7 +14097,7 @@ impl Editor {
         self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
         let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
         let mut selections = self.selections.all::<Point>(cx);
-        let max_point = display_map.buffer_snapshot.max_point();
+        let max_point = display_map.buffer_snapshot().max_point();
         for selection in &mut selections {
             let rows = selection.spanned_rows(true, &display_map);
             selection.start = Point::new(rows.start.0, 0);
@@ -14370,7 +14374,7 @@ impl Editor {
         window: &mut Window,
         cx: &mut Context<Self>,
     ) -> Result<()> {
-        let buffer = &display_map.buffer_snapshot;
+        let buffer = display_map.buffer_snapshot();
         let mut selections = self.selections.all::<usize>(cx);
         if let Some(mut select_next_state) = self.select_next_state.take() {
             let query = &select_next_state.query;
@@ -14533,7 +14537,7 @@ impl Editor {
         let mut new_selections = Vec::new();
 
         let reversed = self.selections.oldest::<usize>(cx).reversed;
-        let buffer = &display_map.buffer_snapshot;
+        let buffer = display_map.buffer_snapshot();
         let query_matches = select_next_state
             .query
             .stream_find_iter(buffer.bytes_in_range(0..buffer.len()));
@@ -14595,7 +14599,7 @@ impl Editor {
     ) -> Result<()> {
         self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
         let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
-        let buffer = &display_map.buffer_snapshot;
+        let buffer = display_map.buffer_snapshot();
         let mut selections = self.selections.all::<usize>(cx);
         if let Some(mut select_prev_state) = self.select_prev_state.take() {
             let query = &select_prev_state.query;
@@ -15513,11 +15517,11 @@ impl Editor {
                     .fold(HashMap::default(), |mut acc, (kind, location, task)| {
                         let buffer = location.target.buffer;
                         let buffer_snapshot = buffer.read(cx).snapshot();
-                        let offset = display_snapshot.buffer_snapshot.excerpts().find_map(
+                        let offset = display_snapshot.buffer_snapshot().excerpts().find_map(
                             |(excerpt_id, snapshot, _)| {
                                 if snapshot.remote_id() == buffer_snapshot.remote_id() {
                                     display_snapshot
-                                        .buffer_snapshot
+                                        .buffer_snapshot()
                                         .anchor_in_excerpt(excerpt_id, location.target.range.start)
                                 } else {
                                     None
@@ -15585,7 +15589,7 @@ impl Editor {
         snapshot: &DisplaySnapshot,
         range: Range<Anchor>,
     ) -> Vec<language::RunnableRange> {
-        snapshot.buffer_snapshot.runnable_ranges(range).collect()
+        snapshot.buffer_snapshot().runnable_ranges(range).collect()
     }
 
     fn runnable_rows(
@@ -15615,9 +15619,12 @@ impl Editor {
                     continue;
                 }
 
-                let point = runnable.run_range.start.to_point(&snapshot.buffer_snapshot);
+                let point = runnable
+                    .run_range
+                    .start
+                    .to_point(&snapshot.buffer_snapshot());
                 let Some(row) = snapshot
-                    .buffer_snapshot
+                    .buffer_snapshot()
                     .buffer_line_for_row(MultiBufferRow(point.row))
                     .map(|(_, range)| range.start.row)
                 else {
@@ -15631,7 +15638,7 @@ impl Editor {
                     RunnableTasks {
                         templates: tasks,
                         offset: snapshot
-                            .buffer_snapshot
+                            .buffer_snapshot()
                             .anchor_before(runnable.run_range.start),
                         context_range,
                         column: point.column,
@@ -16088,12 +16095,12 @@ impl Editor {
         position: Point,
     ) -> Option<MultiBufferDiffHunk> {
         snapshot
-            .buffer_snapshot
-            .diff_hunks_in_range(position..snapshot.buffer_snapshot.max_point())
+            .buffer_snapshot()
+            .diff_hunks_in_range(position..snapshot.buffer_snapshot().max_point())
             .find(|hunk| hunk.row_range.start.0 > position.row)
             .or_else(|| {
                 snapshot
-                    .buffer_snapshot
+                    .buffer_snapshot()
                     .diff_hunks_in_range(Point::zero()..position)
                     .find(|hunk| hunk.row_range.end.0 < position.row)
             })
@@ -16123,9 +16130,9 @@ impl Editor {
         position: Point,
     ) -> Option<MultiBufferRow> {
         snapshot
-            .buffer_snapshot
+            .buffer_snapshot()
             .diff_hunk_before(position)
-            .or_else(|| snapshot.buffer_snapshot.diff_hunk_before(Point::MAX))
+            .or_else(|| snapshot.buffer_snapshot().diff_hunk_before(Point::MAX))
     }
 
     fn go_to_next_change(
@@ -16196,7 +16203,7 @@ impl Editor {
     ) {
         self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
         let snapshot = self.snapshot(window, cx);
-        let buffer = &snapshot.buffer_snapshot;
+        let buffer = &snapshot.buffer_snapshot();
         let position = self.selections.newest::<Point>(cx).head();
         let anchor_position = buffer.anchor_after(position);
 
@@ -16259,13 +16266,13 @@ impl Editor {
         cx: &mut Context<Self>,
     ) {
         let snapshot = self.snapshot(window, cx).display_snapshot;
-        let position = position.to_point(&snapshot.buffer_snapshot);
+        let position = position.to_point(&snapshot.buffer_snapshot());
         let start = snapshot
-            .buffer_snapshot
+            .buffer_snapshot()
             .clip_point(Point::new(position.row, 0), Bias::Left);
         let end = start + Point::new(1, 0);
-        let start = snapshot.buffer_snapshot.anchor_before(start);
-        let end = snapshot.buffer_snapshot.anchor_before(end);
+        let start = snapshot.buffer_snapshot().anchor_before(start);
+        let end = snapshot.buffer_snapshot().anchor_before(end);
 
         self.highlight_rows::<T>(
             start..end,
@@ -18078,7 +18085,7 @@ impl Editor {
         if self.buffer.read(cx).is_singleton() {
             let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
             let has_folds = display_map
-                .folds_in_range(0..display_map.buffer_snapshot.len())
+                .folds_in_range(0..display_map.buffer_snapshot().len())
                 .next()
                 .is_some();
 
@@ -18275,7 +18282,7 @@ impl Editor {
     pub fn unfold_lines(&mut self, _: &UnfoldLines, _window: &mut Window, cx: &mut Context<Self>) {
         if self.buffer_kind(cx) == ItemBufferKind::Singleton {
             let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
-            let buffer = &display_map.buffer_snapshot;
+            let buffer = display_map.buffer_snapshot();
             let selections = self.selections.all::<Point>(cx);
             let ranges = selections
                 .iter()
@@ -18337,7 +18344,7 @@ impl Editor {
         let intersection_range = Point::new(buffer_row.0, 0)
             ..Point::new(
                 buffer_row.0,
-                display_map.buffer_snapshot.line_len(buffer_row),
+                display_map.buffer_snapshot().line_len(buffer_row),
             );
 
         let autoscroll = self
@@ -18357,7 +18364,7 @@ impl Editor {
     ) {
         if self.buffer.read(cx).is_singleton() {
             let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
-            self.unfold_ranges(&[0..display_map.buffer_snapshot.len()], true, true, cx);
+            self.unfold_ranges(&[0..display_map.buffer_snapshot().len()], true, true, cx);
         } else {
             self.toggle_fold_multiple_buffers = cx.spawn(async move |editor, cx| {
                 editor
@@ -18713,8 +18720,8 @@ impl Editor {
         let snapshot = self.snapshot(window, cx);
         let position = self.selections.newest::<Point>(cx).head();
         let mut row = snapshot
-            .buffer_snapshot
-            .diff_hunks_in_range(position..snapshot.buffer_snapshot.max_point())
+            .buffer_snapshot()
+            .diff_hunks_in_range(position..snapshot.buffer_snapshot().max_point())
             .find(|hunk| hunk.row_range.start.0 > position.row)
             .map(|hunk| hunk.row_range.start);
 
@@ -18723,7 +18730,7 @@ impl Editor {
         if !all_diff_hunks_expanded {
             row = row.or_else(|| {
                 snapshot
-                    .buffer_snapshot
+                    .buffer_snapshot()
                     .diff_hunks_in_range(Point::zero()..position)
                     .find(|hunk| hunk.row_range.end.0 < position.row)
                     .map(|hunk| hunk.row_range.start)
@@ -19596,7 +19603,7 @@ impl Editor {
         let blame = self.blame.as_ref()?;
         let snapshot = self.snapshot(window, cx);
         let cursor = self.selections.newest::<Point>(cx).head();
-        let (buffer, point, _) = snapshot.buffer_snapshot.point_to_buffer_point(cursor)?;
+        let (buffer, point, _) = snapshot.buffer_snapshot().point_to_buffer_point(cursor)?;
         let (_, blame_entry) = blame
             .update(cx, |blame, cx| {
                 blame
@@ -20307,7 +20314,7 @@ impl Editor {
         cx: &mut Context<Self>,
     ) -> Vec<(Range<DisplayPoint>, Hsla)> {
         let snapshot = self.snapshot(window, cx);
-        let buffer = &snapshot.buffer_snapshot;
+        let buffer = &snapshot.buffer_snapshot();
         let start = buffer.anchor_before(0);
         let end = buffer.anchor_after(buffer.len());
         self.sorted_background_highlights_in_range(start..end, &snapshot, cx.theme())
@@ -20407,7 +20414,7 @@ impl Editor {
             let start_ix = match ranges.binary_search_by(|probe| {
                 let cmp = probe
                     .end
-                    .cmp(&search_range.start, &display_snapshot.buffer_snapshot);
+                    .cmp(&search_range.start, &display_snapshot.buffer_snapshot());
                 if cmp.is_gt() {
                     Ordering::Greater
                 } else {
@@ -20419,7 +20426,7 @@ impl Editor {
             for range in &ranges[start_ix..] {
                 if range
                     .start
-                    .cmp(&search_range.end, &display_snapshot.buffer_snapshot)
+                    .cmp(&search_range.end, &display_snapshot.buffer_snapshot())
                     .is_ge()
                 {
                     break;
@@ -20445,7 +20452,7 @@ impl Editor {
             let start_ix = match ranges.binary_search_by(|probe| {
                 let cmp = probe
                     .end
-                    .cmp(&search_range.start, &display_snapshot.buffer_snapshot);
+                    .cmp(&search_range.start, &display_snapshot.buffer_snapshot());
                 if cmp.is_gt() {
                     Ordering::Greater
                 } else {
@@ -20457,7 +20464,7 @@ impl Editor {
             for range in &ranges[start_ix..] {
                 if range
                     .start
-                    .cmp(&search_range.end, &display_snapshot.buffer_snapshot)
+                    .cmp(&search_range.end, &display_snapshot.buffer_snapshot())
                     .is_ge()
                 {
                     break;
@@ -20479,7 +20486,7 @@ impl Editor {
         cx: &App,
     ) -> Vec<Range<DisplayPoint>> {
         display_snapshot
-            .buffer_snapshot
+            .buffer_snapshot()
             .redacted_ranges(search_range, |file| {
                 if let Some(file) = file {
                     file.is_private()
@@ -21597,9 +21604,9 @@ impl Editor {
             .all::<usize>(cx)
             .into_iter()
             .map(|selection| {
-                snapshot.buffer_snapshot.anchor_after(selection.end)
+                snapshot.buffer_snapshot().anchor_after(selection.end)
                     ..snapshot
-                        .buffer_snapshot
+                        .buffer_snapshot()
                         .anchor_before(selection.end + pending.len())
             })
             .collect();
@@ -23218,7 +23225,7 @@ impl EditorSnapshot {
             .values()
             .map(|collaborator| (collaborator.replica_id, collaborator))
             .collect::<HashMap<_, _>>();
-        self.buffer_snapshot
+        self.buffer_snapshot()
             .selections_in_range(range, false)
             .filter_map(move |(replica_id, line_mode, cursor_shape, selection)| {
                 if replica_id == AGENT_REPLICA_ID {
@@ -23262,7 +23269,7 @@ impl EditorSnapshot {
         for query_range in ranges {
             let query_rows =
                 MultiBufferRow(query_range.start.row)..MultiBufferRow(query_range.end.row + 1);
-            for hunk in self.buffer_snapshot.diff_hunks_in_range(
+            for hunk in self.buffer_snapshot().diff_hunks_in_range(
                 Point::new(query_rows.start.0, 0)..Point::new(query_rows.end.0, 0),
             ) {
                 // Include deleted hunks that are adjacent to the query range, because
@@ -23296,7 +23303,7 @@ impl EditorSnapshot {
         let buffer_start = DisplayPoint::new(display_rows.start, 0).to_point(self);
         let buffer_end = DisplayPoint::new(display_rows.end, 0).to_point(self);
 
-        self.buffer_snapshot
+        self.buffer_snapshot()
             .diff_hunks_in_range(buffer_start..buffer_end)
             .filter_map(|hunk| {
                 if folded_buffers.contains(&hunk.buffer_id) {
@@ -23337,7 +23344,9 @@ impl EditorSnapshot {
     }
 
     pub fn language_at<T: ToOffset>(&self, position: T) -> Option<&Arc<Language>> {
-        self.display_snapshot.buffer_snapshot.language_at(position)
+        self.display_snapshot
+            .buffer_snapshot()
+            .language_at(position)
     }
 
     pub fn is_focused(&self) -> bool {
@@ -23408,7 +23417,7 @@ impl EditorSnapshot {
                     ch_advance * max_char_count
                 });
 
-        let is_singleton = self.buffer_snapshot.is_singleton();
+        let is_singleton = self.buffer_snapshot().is_singleton();
 
         let mut left_padding = git_blame_entries_width.unwrap_or(Pixels::ZERO);
         left_padding += if !is_singleton {
@@ -23457,7 +23466,7 @@ impl EditorSnapshot {
 
         if let Some(crease) = self
             .crease_snapshot
-            .query_row(buffer_row, &self.buffer_snapshot)
+            .query_row(buffer_row, self.buffer_snapshot())
         {
             is_foldable = true;
             match crease {
@@ -23516,7 +23525,7 @@ impl EditorSnapshot {
         let folded = self.is_line_folded(buffer_row);
         if let Crease::Inline { render_trailer, .. } = self
             .crease_snapshot
-            .query_row(buffer_row, &self.buffer_snapshot)?
+            .query_row(buffer_row, self.buffer_snapshot())?
         {
             let render_trailer = render_trailer.as_ref()?;
             Some(render_trailer(buffer_row, folded, window, cx))
@@ -23947,7 +23956,7 @@ impl EntityInputHandler for Editor {
         let anchor = position_map
             .snapshot
             .display_point_to_anchor(display_point, Bias::Left);
-        let utf16_offset = anchor.to_offset_utf16(&position_map.snapshot.buffer_snapshot);
+        let utf16_offset = anchor.to_offset_utf16(&position_map.snapshot.buffer_snapshot());
         Some(utf16_offset.0)
     }
 }
@@ -23965,11 +23974,11 @@ impl<T: ToPoint + ToOffset> SelectionExt for Selection<T> {
     fn display_range(&self, map: &DisplaySnapshot) -> Range<DisplayPoint> {
         let start = self
             .start
-            .to_point(&map.buffer_snapshot)
+            .to_point(map.buffer_snapshot())
             .to_display_point(map);
         let end = self
             .end
-            .to_point(&map.buffer_snapshot)
+            .to_point(map.buffer_snapshot())
             .to_display_point(map);
         if self.reversed {
             end..start
@@ -23983,8 +23992,8 @@ impl<T: ToPoint + ToOffset> SelectionExt for Selection<T> {
         include_end_if_at_line_start: bool,
         map: &DisplaySnapshot,
     ) -> Range<MultiBufferRow> {
-        let start = self.start.to_point(&map.buffer_snapshot);
-        let mut end = self.end.to_point(&map.buffer_snapshot);
+        let start = self.start.to_point(map.buffer_snapshot());
+        let mut end = self.end.to_point(map.buffer_snapshot());
         if !include_end_if_at_line_start && start.row != end.row && end.column == 0 {
             end.row -= 1;
         }
@@ -24174,7 +24183,7 @@ pub trait RangeToAnchorExt: Sized {
     fn to_anchors(self, snapshot: &MultiBufferSnapshot) -> Range<Anchor>;
 
     fn to_display_points(self, snapshot: &EditorSnapshot) -> Range<DisplayPoint> {
-        let anchor_range = self.to_anchors(&snapshot.buffer_snapshot);
+        let anchor_range = self.to_anchors(&snapshot.buffer_snapshot());
         anchor_range.start.to_display_point(snapshot)..anchor_range.end.to_display_point(snapshot)
     }
 }
@@ -24635,7 +24644,7 @@ fn render_diff_hunk_controls(
                     move |_event, window, cx| {
                         editor.update(cx, |editor, cx| {
                             let snapshot = editor.snapshot(window, cx);
-                            let point = hunk_range.start.to_point(&snapshot.buffer_snapshot);
+                            let point = hunk_range.start.to_point(&snapshot.buffer_snapshot());
                             editor.restore_hunks_in_ranges(vec![point..point], window, cx);
                         });
                     }
@@ -24668,7 +24677,7 @@ fn render_diff_hunk_controls(
                                 editor.update(cx, |editor, cx| {
                                     let snapshot = editor.snapshot(window, cx);
                                     let position =
-                                        hunk_range.end.to_point(&snapshot.buffer_snapshot);
+                                        hunk_range.end.to_point(&snapshot.buffer_snapshot());
                                     editor.go_to_hunk_before_or_after_position(
                                         &snapshot,
                                         position,
@@ -24704,7 +24713,7 @@ fn render_diff_hunk_controls(
                                 editor.update(cx, |editor, cx| {
                                     let snapshot = editor.snapshot(window, cx);
                                     let point =
-                                        hunk_range.start.to_point(&snapshot.buffer_snapshot);
+                                        hunk_range.start.to_point(&snapshot.buffer_snapshot());
                                     editor.go_to_hunk_before_or_after_position(
                                         &snapshot,
                                         point,

crates/editor/src/editor_tests.rs 🔗

@@ -4527,8 +4527,8 @@ async fn test_custom_newlines_cause_no_false_positive_diffs(
         let snapshot = editor.snapshot(window, cx);
         assert_eq!(
             snapshot
-                .buffer_snapshot
-                .diff_hunks_in_range(0..snapshot.buffer_snapshot.len())
+                .buffer_snapshot()
+                .diff_hunks_in_range(0..snapshot.buffer_snapshot().len())
                 .collect::<Vec<_>>(),
             Vec::new(),
             "Should not have any diffs for files with custom newlines"
@@ -5742,7 +5742,7 @@ async fn test_selections_and_replace_blocks(cx: &mut TestAppContext) {
     // Create a four-line block that replaces three lines of text.
     cx.update_editor(|editor, window, cx| {
         let snapshot = editor.snapshot(window, cx);
-        let snapshot = &snapshot.buffer_snapshot;
+        let snapshot = &snapshot.buffer_snapshot();
         let placement = BlockPlacement::Replace(
             snapshot.anchor_after(Point::new(1, 0))..=snapshot.anchor_after(Point::new(3, 0)),
         );
@@ -20739,7 +20739,7 @@ async fn test_indent_guide_with_expanded_diff_hunks(cx: &mut TestAppContext) {
     let mut actual_guides = cx.update_editor(|editor, window, cx| {
         editor
             .snapshot(window, cx)
-            .buffer_snapshot
+            .buffer_snapshot()
             .indent_guides_in_range(Anchor::min()..Anchor::max(), false, cx)
             .map(|guide| (guide.start_row..=guide.end_row, guide.depth))
             .collect::<Vec<_>>()
@@ -20795,7 +20795,7 @@ async fn test_adjacent_diff_hunks(executor: BackgroundExecutor, cx: &mut TestApp
     let hunk_ranges = cx.update_editor(|editor, window, cx| {
         let snapshot = editor.snapshot(window, cx);
         let hunks = editor
-            .diff_hunks_in_ranges(&[Anchor::min()..Anchor::max()], &snapshot.buffer_snapshot)
+            .diff_hunks_in_ranges(&[Anchor::min()..Anchor::max()], &snapshot.buffer_snapshot())
             .collect::<Vec<_>>();
         let excerpt_id = editor.buffer.read(cx).excerpt_ids()[0];
         let buffer_id = hunks[0].buffer_id;
@@ -20886,7 +20886,7 @@ async fn test_adjacent_diff_hunks(executor: BackgroundExecutor, cx: &mut TestApp
     let hunk_ranges = cx.update_editor(|editor, window, cx| {
         let snapshot = editor.snapshot(window, cx);
         let hunks = editor
-            .diff_hunks_in_ranges(&[Anchor::min()..Anchor::max()], &snapshot.buffer_snapshot)
+            .diff_hunks_in_ranges(&[Anchor::min()..Anchor::max()], &snapshot.buffer_snapshot())
             .collect::<Vec<_>>();
         let excerpt_id = editor.buffer.read(cx).excerpt_ids()[0];
         let buffer_id = hunks[0].buffer_id;
@@ -20952,7 +20952,7 @@ async fn test_toggle_deletion_hunk_at_start_of_file(
     let hunk_ranges = cx.update_editor(|editor, window, cx| {
         let snapshot = editor.snapshot(window, cx);
         let hunks = editor
-            .diff_hunks_in_ranges(&[Anchor::min()..Anchor::max()], &snapshot.buffer_snapshot)
+            .diff_hunks_in_ranges(&[Anchor::min()..Anchor::max()], &snapshot.buffer_snapshot())
             .collect::<Vec<_>>();
         let excerpt_id = editor.buffer.read(cx).excerpt_ids()[0];
         let buffer_id = hunks[0].buffer_id;
@@ -21117,7 +21117,7 @@ async fn test_partially_staged_hunk(cx: &mut TestAppContext) {
     cx.update_editor(|editor, window, cx| {
         let snapshot = editor.snapshot(window, cx);
         let hunks = editor
-            .diff_hunks_in_ranges(&[Anchor::min()..Anchor::max()], &snapshot.buffer_snapshot)
+            .diff_hunks_in_ranges(&[Anchor::min()..Anchor::max()], &snapshot.buffer_snapshot())
             .collect::<Vec<_>>();
         assert_eq!(hunks.len(), 1);
         assert_eq!(
@@ -22572,7 +22572,7 @@ fn add_log_breakpoint_at_cursor(
             let breakpoint_position = editor
                 .snapshot(window, cx)
                 .display_snapshot
-                .buffer_snapshot
+                .buffer_snapshot()
                 .anchor_before(Point::new(cursor_position.row, 0));
 
             (breakpoint_position, Breakpoint::new_log(log_message))
@@ -25364,8 +25364,8 @@ fn assert_hunk_revert(
     let actual_hunk_statuses_before = cx.update_editor(|editor, window, cx| {
         let snapshot = editor.snapshot(window, cx);
         let reverted_hunk_statuses = snapshot
-            .buffer_snapshot
-            .diff_hunks_in_range(0..snapshot.buffer_snapshot.len())
+            .buffer_snapshot()
+            .diff_hunks_in_range(0..snapshot.buffer_snapshot().len())
             .map(|hunk| hunk.status().kind)
             .collect::<Vec<_>>();
 

crates/editor/src/element.rs 🔗

@@ -136,7 +136,7 @@ impl SelectionLayout {
         is_local: bool,
         user_name: Option<SharedString>,
     ) -> Self {
-        let point_selection = selection.map(|p| p.to_point(&map.buffer_snapshot));
+        let point_selection = selection.map(|p| p.to_point(map.buffer_snapshot()));
         let display_selection = point_selection.map(|p| p.to_display_point(map));
         let mut range = display_selection.range();
         let mut head = display_selection.head();
@@ -1193,7 +1193,7 @@ impl EditorElement {
 
             if let Some((buffer_snapshot, file)) = position_map
                 .snapshot
-                .buffer_snapshot
+                .buffer_snapshot()
                 .buffer_for_excerpt(buffer_anchor.excerpt_id)
                 .and_then(|buffer| buffer.file().map(|file| (buffer, file)))
             {
@@ -1275,7 +1275,7 @@ impl EditorElement {
             if let Some(point) = point_for_position.as_valid() {
                 let anchor = position_map
                     .snapshot
-                    .buffer_snapshot
+                    .buffer_snapshot()
                     .anchor_before(point.to_offset(&position_map.snapshot, Bias::Left));
                 hover_at(editor, Some(anchor), window, cx);
                 Self::update_visible_cursor(editor, point, position_map, window, cx);
@@ -1312,10 +1312,10 @@ impl EditorElement {
         );
 
         let range = snapshot
-            .buffer_snapshot
+            .buffer_snapshot()
             .anchor_before(start.to_point(&snapshot.display_snapshot))
             ..snapshot
-                .buffer_snapshot
+                .buffer_snapshot()
                 .anchor_after(end.to_point(&snapshot.display_snapshot));
 
         let Some(selection) = snapshot.remote_selections_in_range(&range, hub, cx).next() else {
@@ -1406,11 +1406,11 @@ impl EditorElement {
                     && !hide_drop_cursor
                     && (drop_cursor
                         .start
-                        .cmp(&selection.start, &snapshot.buffer_snapshot)
+                        .cmp(&selection.start, &snapshot.buffer_snapshot())
                         .eq(&Ordering::Less)
                         || drop_cursor
                             .end
-                            .cmp(&selection.end, &snapshot.buffer_snapshot)
+                            .cmp(&selection.end, &snapshot.buffer_snapshot())
                             .eq(&Ordering::Greater))
                 {
                     let drag_cursor_layout = SelectionLayout::new(
@@ -1490,7 +1490,7 @@ impl EditorElement {
                 selections.extend(remote_selections.into_values());
             } else if !editor.is_focused(window) && editor.show_cursor_when_unfocused {
                 let layouts = snapshot
-                    .buffer_snapshot
+                    .buffer_snapshot()
                     .selections_in_range(&(start_anchor..end_anchor), true)
                     .map(move |(_, line_mode, cursor_shape, selection)| {
                         SelectionLayout::new(
@@ -1768,7 +1768,7 @@ impl EditorElement {
                 let editor = self.editor.read(cx);
                 let is_singleton = editor.buffer_kind(cx) == ItemBufferKind::Singleton;
                 // Git
-                (is_singleton && scrollbar_settings.git_diff && snapshot.buffer_snapshot.has_diff_hunks())
+                (is_singleton && scrollbar_settings.git_diff && snapshot.buffer_snapshot().has_diff_hunks())
                 ||
                 // Buffer Search Results
                 (is_singleton && scrollbar_settings.search_results && editor.has_background_highlights::<BufferSearchHighlights>())
@@ -1780,7 +1780,7 @@ impl EditorElement {
                 (is_singleton && scrollbar_settings.selected_symbol && (editor.has_background_highlights::<DocumentHighlightRead>() || editor.has_background_highlights::<DocumentHighlightWrite>()))
                 ||
                 // Diagnostics
-                (is_singleton && scrollbar_settings.diagnostics != ScrollbarDiagnostics::None && snapshot.buffer_snapshot.has_diagnostics())
+                (is_singleton && scrollbar_settings.diagnostics != ScrollbarDiagnostics::None && snapshot.buffer_snapshot().has_diagnostics())
                 ||
                 // Cursors out of sight
                 non_visible_cursors
@@ -2342,7 +2342,7 @@ impl EditorElement {
         // do not show code action for blank line with cursor
         let line_indent = snapshot
             .display_snapshot
-            .buffer_snapshot
+            .buffer_snapshot()
             .line_indent_for_row(MultiBufferRow(buffer_point.row));
         if line_indent.is_line_blank() {
             return None;
@@ -2353,7 +2353,7 @@ impl EditorElement {
 
         let excerpt_id = snapshot
             .display_snapshot
-            .buffer_snapshot
+            .buffer_snapshot()
             .excerpt_containing(buffer_point..buffer_point)
             .map(|excerpt| excerpt.id());
 
@@ -2374,7 +2374,7 @@ impl EditorElement {
                 };
                 let candidate_excerpt_id = snapshot
                     .display_snapshot
-                    .buffer_snapshot
+                    .buffer_snapshot()
                     .excerpt_containing(candidate_point..candidate_point)
                     .map(|excerpt| excerpt.id());
                 // move to other row if different excerpt
@@ -2384,7 +2384,7 @@ impl EditorElement {
             }
             let line_indent = snapshot
                 .display_snapshot
-                .buffer_snapshot
+                .buffer_snapshot()
                 .line_indent_for_row(MultiBufferRow(row_candidate));
             // use this row if it's blank
             if line_indent.is_line_blank() {
@@ -2393,7 +2393,7 @@ impl EditorElement {
                 // use this row if code starts after slot
                 let indent_size = snapshot
                     .display_snapshot
-                    .buffer_snapshot
+                    .buffer_snapshot()
                     .indent_size_for_line(MultiBufferRow(row_candidate));
                 indent_size.len >= INLINE_SLOT_CHAR_LIMIT
             }
@@ -2402,7 +2402,7 @@ impl EditorElement {
         let new_buffer_row = if is_valid_row(buffer_point.row) {
             Some(buffer_point.row)
         } else {
-            let max_row = snapshot.display_snapshot.buffer_snapshot.max_point().row;
+            let max_row = snapshot.display_snapshot.buffer_snapshot().max_point().row;
             (1..=MAX_ALTERNATE_DISTANCE).find_map(|offset| {
                 let row_above = buffer_point.row.saturating_sub(offset);
                 let row_below = buffer_point.row + offset;
@@ -2951,7 +2951,7 @@ impl EditorElement {
                 .tasks
                 .iter()
                 .filter_map(|(_, tasks)| {
-                    let multibuffer_point = tasks.offset.to_point(&snapshot.buffer_snapshot);
+                    let multibuffer_point = tasks.offset.to_point(&snapshot.buffer_snapshot());
                     if multibuffer_point < offset_range_start
                         || multibuffer_point > offset_range_end
                     {
@@ -2959,7 +2959,7 @@ impl EditorElement {
                     }
                     let multibuffer_row = MultiBufferRow(multibuffer_point.row);
                     let buffer_folded = snapshot
-                        .buffer_snapshot
+                        .buffer_snapshot()
                         .buffer_line_for_row(multibuffer_row)
                         .map(|(buffer_snapshot, _)| buffer_snapshot.remote_id())
                         .map(|buffer_id| editor.is_buffer_folded(buffer_id, cx))
@@ -3605,8 +3605,8 @@ impl EditorElement {
         let mut x_position = None;
         let mut element = match block {
             Block::Custom(custom) => {
-                let block_start = custom.start().to_point(&snapshot.buffer_snapshot);
-                let block_end = custom.end().to_point(&snapshot.buffer_snapshot);
+                let block_start = custom.start().to_point(&snapshot.buffer_snapshot());
+                let block_end = custom.end().to_point(&snapshot.buffer_snapshot());
                 if block.place_near() && snapshot.is_line_folded(MultiBufferRow(block_start.row)) {
                     return None;
                 }
@@ -6643,11 +6643,11 @@ impl EditorElement {
                     let scrollbar_size = scrollbar_layout.hitbox.size;
                     let scrollbar_markers = cx
                         .background_spawn(async move {
-                            let max_point = snapshot.display_snapshot.buffer_snapshot.max_point();
+                            let max_point = snapshot.display_snapshot.buffer_snapshot().max_point();
                             let mut marker_quads = Vec::new();
                             if scrollbar_settings.git_diff {
                                 let marker_row_ranges =
-                                    snapshot.buffer_snapshot.diff_hunks().map(|hunk| {
+                                    snapshot.buffer_snapshot().diff_hunks().map(|hunk| {
                                         let start_display_row =
                                             MultiBufferPoint::new(hunk.row_range.start.0, 0)
                                                 .to_display_point(&snapshot.display_snapshot)
@@ -6725,7 +6725,7 @@ impl EditorElement {
 
                             if scrollbar_settings.diagnostics != ScrollbarDiagnostics::None {
                                 let diagnostics = snapshot
-                                    .buffer_snapshot
+                                    .buffer_snapshot()
                                     .diagnostics_in_range::<Point>(Point::zero()..max_point)
                                     // Don't show diagnostics the user doesn't care about
                                     .filter(|diagnostic| {
@@ -7429,7 +7429,7 @@ impl EditorElement {
             if debug_ranges.ranges.is_empty() {
                 return;
             }
-            let buffer_snapshot = &display_snapshot.buffer_snapshot;
+            let buffer_snapshot = &display_snapshot.buffer_snapshot();
             for (buffer, buffer_range, excerpt_id) in
                 buffer_snapshot.range_to_buffer_ranges(anchor_range)
             {
@@ -8668,14 +8668,14 @@ impl Element for EditorElement {
                     let start_anchor = if start_row == Default::default() {
                         Anchor::min()
                     } else {
-                        snapshot.buffer_snapshot.anchor_before(
+                        snapshot.buffer_snapshot().anchor_before(
                             DisplayPoint::new(start_row, 0).to_offset(&snapshot, Bias::Left),
                         )
                     };
                     let end_anchor = if end_row > max_row {
                         Anchor::max()
                     } else {
-                        snapshot.buffer_snapshot.anchor_before(
+                        snapshot.buffer_snapshot().anchor_before(
                             DisplayPoint::new(end_row, 0).to_offset(&snapshot, Bias::Right),
                         )
                     };
@@ -8784,7 +8784,7 @@ impl Element for EditorElement {
 
                                         for selection in all_selections {
                                             for buffer_id in snapshot
-                                                .buffer_snapshot
+                                                .buffer_snapshot()
                                                 .buffer_ids_for_range(selection.range())
                                             {
                                                 if selected_buffer_ids.last() != Some(&buffer_id) {
@@ -9000,7 +9000,7 @@ impl Element for EditorElement {
 
                     let mut scroll_width = scrollbar_layout_information.scroll_range.width;
 
-                    let sticky_header_excerpt = if snapshot.buffer_snapshot.show_headers() {
+                    let sticky_header_excerpt = if snapshot.buffer_snapshot().show_headers() {
                         snapshot.sticky_header_excerpt(scroll_position.y)
                     } else {
                         None
@@ -9065,9 +9065,9 @@ impl Element for EditorElement {
                     });
 
                     let start_buffer_row =
-                        MultiBufferRow(start_anchor.to_point(&snapshot.buffer_snapshot).row);
+                        MultiBufferRow(start_anchor.to_point(&snapshot.buffer_snapshot()).row);
                     let end_buffer_row =
-                        MultiBufferRow(end_anchor.to_point(&snapshot.buffer_snapshot).row);
+                        MultiBufferRow(end_anchor.to_point(&snapshot.buffer_snapshot()).row);
 
                     let scroll_max: gpui::Point<ScrollPixelOffset> = point(
                         ScrollPixelOffset::from(

crates/editor/src/highlight_matching_bracket.rs 🔗

@@ -20,28 +20,28 @@ pub fn refresh_matching_bracket_highlights(
 
     let snapshot = editor.snapshot(window, cx);
     let head = newest_selection.head();
-    if head > snapshot.buffer_snapshot.len() {
+    if head > snapshot.buffer_snapshot().len() {
         log::error!("bug: cursor offset is out of range while refreshing bracket highlights");
         return;
     }
 
     let mut tail = head;
     if (editor.cursor_shape == CursorShape::Block || editor.cursor_shape == CursorShape::Hollow)
-        && head < snapshot.buffer_snapshot.len()
+        && head < snapshot.buffer_snapshot().len()
     {
-        if let Some(tail_ch) = snapshot.buffer_snapshot.chars_at(tail).next() {
+        if let Some(tail_ch) = snapshot.buffer_snapshot().chars_at(tail).next() {
             tail += tail_ch.len_utf8();
         }
     }
 
     if let Some((opening_range, closing_range)) = snapshot
-        .buffer_snapshot
+        .buffer_snapshot()
         .innermost_enclosing_bracket_ranges(head..tail, None)
     {
         editor.highlight_text::<MatchingBracketHighlight>(
             vec![
-                opening_range.to_anchors(&snapshot.buffer_snapshot),
-                closing_range.to_anchors(&snapshot.buffer_snapshot),
+                opening_range.to_anchors(&snapshot.buffer_snapshot()),
+                closing_range.to_anchors(&snapshot.buffer_snapshot()),
             ],
             HighlightStyle {
                 background_color: Some(

crates/editor/src/hover_links.rs 🔗

@@ -49,8 +49,8 @@ impl RangeInEditor {
     ) -> bool {
         match (self, trigger_point) {
             (Self::Text(range), TriggerPoint::Text(point)) => {
-                let point_after_start = range.start.cmp(point, &snapshot.buffer_snapshot).is_le();
-                point_after_start && range.end.cmp(point, &snapshot.buffer_snapshot).is_ge()
+                let point_after_start = range.start.cmp(point, &snapshot.buffer_snapshot()).is_le();
+                point_after_start && range.end.cmp(point, &snapshot.buffer_snapshot()).is_ge()
             }
             (Self::Inlay(highlight), TriggerPoint::InlayHint(point, _, _)) => {
                 highlight.inlay == point.inlay
@@ -131,7 +131,7 @@ impl Editor {
             Some(point) => {
                 let trigger_point = TriggerPoint::Text(
                     snapshot
-                        .buffer_snapshot
+                        .buffer_snapshot()
                         .anchor_before(point.to_offset(&snapshot.display_snapshot, Bias::Left)),
                 );
 
@@ -326,7 +326,7 @@ pub fn update_inlay_link_and_hover_points(
                 match cached_hint.resolve_state {
                     ResolveState::CanResolve(_, _) => {
                         if let Some(buffer_id) = snapshot
-                            .buffer_snapshot
+                            .buffer_snapshot()
                             .buffer_id_for_anchor(previous_valid_anchor)
                         {
                             inlay_hint_cache.spawn_hint_resolve(
@@ -534,7 +534,7 @@ pub fn show_link_definition(
     let project = editor.project.clone();
     let provider = editor.semantics_provider.clone();
 
-    let snapshot = snapshot.buffer_snapshot.clone();
+    let snapshot = snapshot.buffer_snapshot().clone();
     hovered_link_state.task = Some(cx.spawn_in(window, async move |this, cx| {
         async move {
             let result = match &trigger_point {

crates/editor/src/hover_popover.rs 🔗

@@ -269,7 +269,7 @@ fn show_hover(
     // Don't request again if the location is the same as the previous request
     if let Some(triggered_from) = &editor.hover_state.triggered_from
         && triggered_from
-            .cmp(&anchor, &snapshot.buffer_snapshot)
+            .cmp(&anchor, &snapshot.buffer_snapshot())
             .is_eq()
     {
         return None;
@@ -308,12 +308,12 @@ fn show_hover(
                 delay.await;
             }
 
-            let offset = anchor.to_offset(&snapshot.buffer_snapshot);
+            let offset = anchor.to_offset(&snapshot.buffer_snapshot());
             let local_diagnostic = if all_diagnostics_active {
                 None
             } else {
                 snapshot
-                    .buffer_snapshot
+                    .buffer_snapshot()
                     .diagnostics_with_buffer_ids_in_range::<usize>(offset..offset)
                     .filter(|(_, diagnostic)| {
                         Some(diagnostic.diagnostic.group_id) != active_group_id
@@ -324,17 +324,17 @@ fn show_hover(
 
             let diagnostic_popover = if let Some((buffer_id, local_diagnostic)) = local_diagnostic {
                 let group = snapshot
-                    .buffer_snapshot
+                    .buffer_snapshot()
                     .diagnostic_group(buffer_id, local_diagnostic.diagnostic.group_id)
                     .collect::<Vec<_>>();
                 let point_range = local_diagnostic
                     .range
                     .start
-                    .to_point(&snapshot.buffer_snapshot)
+                    .to_point(&snapshot.buffer_snapshot())
                     ..local_diagnostic
                         .range
                         .end
-                        .to_point(&snapshot.buffer_snapshot);
+                        .to_point(&snapshot.buffer_snapshot());
                 let markdown = cx.update(|_, cx| {
                     renderer
                         .as_ref()
@@ -373,10 +373,10 @@ fn show_hover(
                 let local_diagnostic = DiagnosticEntry {
                     diagnostic: local_diagnostic.diagnostic.to_owned(),
                     range: snapshot
-                        .buffer_snapshot
+                        .buffer_snapshot()
                         .anchor_before(local_diagnostic.range.start)
                         ..snapshot
-                            .buffer_snapshot
+                            .buffer_snapshot()
                             .anchor_after(local_diagnostic.range.end),
                 };
 
@@ -401,23 +401,23 @@ fn show_hover(
             })?;
 
             let invisible_char = if let Some(invisible) = snapshot
-                .buffer_snapshot
+                .buffer_snapshot()
                 .chars_at(anchor)
                 .next()
                 .filter(|&c| is_invisible(c))
             {
-                let after = snapshot.buffer_snapshot.anchor_after(
-                    anchor.to_offset(&snapshot.buffer_snapshot) + invisible.len_utf8(),
+                let after = snapshot.buffer_snapshot().anchor_after(
+                    anchor.to_offset(&snapshot.buffer_snapshot()) + invisible.len_utf8(),
                 );
                 Some((invisible, anchor..after))
             } else if let Some(invisible) = snapshot
-                .buffer_snapshot
+                .buffer_snapshot()
                 .reversed_chars_at(anchor)
                 .next()
                 .filter(|&c| is_invisible(c))
             {
-                let before = snapshot.buffer_snapshot.anchor_before(
-                    anchor.to_offset(&snapshot.buffer_snapshot) - invisible.len_utf8(),
+                let before = snapshot.buffer_snapshot().anchor_before(
+                    anchor.to_offset(&snapshot.buffer_snapshot()) - invisible.len_utf8(),
                 );
 
                 Some((invisible, before..anchor))
@@ -468,15 +468,15 @@ fn show_hover(
                     .range
                     .and_then(|range| {
                         let start = snapshot
-                            .buffer_snapshot
+                            .buffer_snapshot()
                             .anchor_in_excerpt(excerpt_id, range.start)?;
                         let end = snapshot
-                            .buffer_snapshot
+                            .buffer_snapshot()
                             .anchor_in_excerpt(excerpt_id, range.end)?;
                         Some(start..end)
                     })
                     .or_else(|| {
-                        let snapshot = &snapshot.buffer_snapshot;
+                        let snapshot = &snapshot.buffer_snapshot();
                         let range = snapshot.syntax_ancestor(anchor..anchor)?.1;
                         Some(snapshot.anchor_before(range.start)..snapshot.anchor_after(range.end))
                     })
@@ -542,8 +542,8 @@ fn same_info_hover(editor: &Editor, snapshot: &EditorSnapshot, anchor: Anchor) -
             symbol_range
                 .as_text_range()
                 .map(|range| {
-                    let hover_range = range.to_offset(&snapshot.buffer_snapshot);
-                    let offset = anchor.to_offset(&snapshot.buffer_snapshot);
+                    let hover_range = range.to_offset(&snapshot.buffer_snapshot());
+                    let offset = anchor.to_offset(&snapshot.buffer_snapshot());
                     // LSP returns a hover result for the end index of ranges that should be hovered, so we need to
                     // use an inclusive range here to check if we should dismiss the popover
                     (hover_range.start..=hover_range.end).contains(&offset)
@@ -561,8 +561,8 @@ fn same_diagnostic_hover(editor: &Editor, snapshot: &EditorSnapshot, anchor: Anc
             let hover_range = diagnostic
                 .local_diagnostic
                 .range
-                .to_offset(&snapshot.buffer_snapshot);
-            let offset = anchor.to_offset(&snapshot.buffer_snapshot);
+                .to_offset(&snapshot.buffer_snapshot());
+            let offset = anchor.to_offset(&snapshot.buffer_snapshot());
 
             // Here we do basically the same as in `same_info_hover`, see comment there for an explanation
             (hover_range.start..=hover_range.end).contains(&offset)
@@ -1090,7 +1090,7 @@ mod tests {
         cx.update_editor(|editor, window, cx| {
             let snapshot = editor.snapshot(window, cx);
             let anchor = snapshot
-                .buffer_snapshot
+                .buffer_snapshot()
                 .anchor_before(hover_point.to_offset(&snapshot, Bias::Left));
             hover_at(editor, Some(anchor), window, cx)
         });
@@ -1190,7 +1190,7 @@ mod tests {
         cx.update_editor(|editor, window, cx| {
             let snapshot = editor.snapshot(window, cx);
             let anchor = snapshot
-                .buffer_snapshot
+                .buffer_snapshot()
                 .anchor_before(hover_point.to_offset(&snapshot, Bias::Left));
             hover_at(editor, Some(anchor), window, cx)
         });
@@ -1228,7 +1228,7 @@ mod tests {
         cx.update_editor(|editor, window, cx| {
             let snapshot = editor.snapshot(window, cx);
             let anchor = snapshot
-                .buffer_snapshot
+                .buffer_snapshot()
                 .anchor_before(hover_point.to_offset(&snapshot, Bias::Left));
             hover_at(editor, Some(anchor), window, cx)
         });
@@ -1282,7 +1282,7 @@ mod tests {
         cx.update_editor(|editor, window, cx| {
             let snapshot = editor.snapshot(window, cx);
             let anchor = snapshot
-                .buffer_snapshot
+                .buffer_snapshot()
                 .anchor_before(hover_point.to_offset(&snapshot, Bias::Left));
             hover_at(editor, Some(anchor), window, cx)
         });

crates/editor/src/indent_guides.rs 🔗

@@ -155,19 +155,19 @@ pub fn indent_guides_in_range(
     cx: &App,
 ) -> Vec<IndentGuide> {
     let start_offset = snapshot
-        .buffer_snapshot
+        .buffer_snapshot()
         .point_to_offset(Point::new(visible_buffer_range.start.0, 0));
     let end_offset = snapshot
-        .buffer_snapshot
+        .buffer_snapshot()
         .point_to_offset(Point::new(visible_buffer_range.end.0, 0));
-    let start_anchor = snapshot.buffer_snapshot.anchor_before(start_offset);
-    let end_anchor = snapshot.buffer_snapshot.anchor_after(end_offset);
+    let start_anchor = snapshot.buffer_snapshot().anchor_before(start_offset);
+    let end_anchor = snapshot.buffer_snapshot().anchor_after(end_offset);
 
     let mut fold_ranges = Vec::<Range<Point>>::new();
     let folds = snapshot.folds_in_range(start_offset..end_offset).peekable();
     for fold in folds {
-        let start = fold.range.start.to_point(&snapshot.buffer_snapshot);
-        let end = fold.range.end.to_point(&snapshot.buffer_snapshot);
+        let start = fold.range.start.to_point(&snapshot.buffer_snapshot());
+        let end = fold.range.end.to_point(&snapshot.buffer_snapshot());
         if let Some(last_range) = fold_ranges.last_mut()
             && last_range.end >= start
         {
@@ -178,7 +178,7 @@ pub fn indent_guides_in_range(
     }
 
     snapshot
-        .buffer_snapshot
+        .buffer_snapshot()
         .indent_guides_in_range(start_anchor..end_anchor, ignore_disabled_for_language, cx)
         .filter(|indent_guide| {
             if editor.is_buffer_folded(indent_guide.buffer_id, cx) {
@@ -207,7 +207,7 @@ async fn resolve_indented_range(
     buffer_row: MultiBufferRow,
 ) -> Option<ActiveIndentedRange> {
     snapshot
-        .buffer_snapshot
+        .buffer_snapshot()
         .enclosing_indent(buffer_row)
         .await
         .map(|(row_range, indent)| ActiveIndentedRange { row_range, indent })
@@ -222,23 +222,23 @@ fn should_recalculate_indented_range(
     if prev_row.0 == new_row.0 {
         return false;
     }
-    if snapshot.buffer_snapshot.is_singleton() {
+    if snapshot.buffer_snapshot().is_singleton() {
         if !current_indent_range.row_range.contains(&new_row) {
             return true;
         }
 
-        let old_line_indent = snapshot.buffer_snapshot.line_indent_for_row(prev_row);
-        let new_line_indent = snapshot.buffer_snapshot.line_indent_for_row(new_row);
+        let old_line_indent = snapshot.buffer_snapshot().line_indent_for_row(prev_row);
+        let new_line_indent = snapshot.buffer_snapshot().line_indent_for_row(new_row);
 
         if old_line_indent.is_line_empty()
             || new_line_indent.is_line_empty()
             || old_line_indent != new_line_indent
-            || snapshot.buffer_snapshot.max_point().row == new_row.0
+            || snapshot.buffer_snapshot().max_point().row == new_row.0
         {
             return true;
         }
 
-        let next_line_indent = snapshot.buffer_snapshot.line_indent_for_row(new_row + 1);
+        let next_line_indent = snapshot.buffer_snapshot().line_indent_for_row(new_row + 1);
         next_line_indent.is_line_empty() || next_line_indent != old_line_indent
     } else {
         true

crates/editor/src/items.rs 🔗

@@ -1539,7 +1539,8 @@ impl SearchableItem for Editor {
 
     fn query_suggestion(&mut self, window: &mut Window, cx: &mut Context<Self>) -> String {
         let setting = EditorSettings::get_global(cx).seed_search_query_from_cursor;
-        let snapshot = &self.snapshot(window, cx).buffer_snapshot;
+        let snapshot = self.snapshot(window, cx);
+        let snapshot = snapshot.buffer_snapshot();
         let selection = self.selections.newest_adjusted(cx);
 
         match setting {

crates/editor/src/mouse_context_menu.rs 🔗

@@ -170,7 +170,8 @@ pub fn deploy_context_menu(
         };
 
         let display_map = editor.selections.display_map(cx);
-        let buffer = &editor.snapshot(window, cx).buffer_snapshot;
+        let snapshot = editor.snapshot(window, cx);
+        let buffer = snapshot.buffer_snapshot();
         let anchor = buffer.anchor_before(point.to_point(&display_map));
         if !display_ranges(&display_map, &editor.selections).any(|r| r.contains(&point)) {
             // Move the cursor to the clicked location so that dispatched actions make sense

crates/editor/src/movement.rs 🔗

@@ -223,7 +223,7 @@ pub fn indented_line_beginning(
     let soft_line_start = map.clip_point(DisplayPoint::new(display_point.row(), 0), Bias::Right);
     let indent_start = Point::new(
         point.row,
-        map.buffer_snapshot
+        map.buffer_snapshot()
             .indent_size_for_line(MultiBufferRow(point.row))
             .len,
     )
@@ -265,7 +265,7 @@ pub fn line_end(
 /// uppercase letter, lowercase letter, '_' character or language-specific word character (like '-' in CSS).
 pub fn previous_word_start(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint {
     let raw_point = point.to_point(map);
-    let classifier = map.buffer_snapshot.char_classifier_at(raw_point);
+    let classifier = map.buffer_snapshot().char_classifier_at(raw_point);
 
     let mut is_first_iteration = true;
     find_preceding_boundary_display_point(map, point, FindRange::MultiLine, |left, right| {
@@ -289,7 +289,7 @@ pub fn previous_word_start(map: &DisplaySnapshot, point: DisplayPoint) -> Displa
 /// uppercase letter, lowercase letter, '_' character, language-specific word character (like '-' in CSS) or newline.
 pub fn previous_word_start_or_newline(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint {
     let raw_point = point.to_point(map);
-    let classifier = map.buffer_snapshot.char_classifier_at(raw_point);
+    let classifier = map.buffer_snapshot().char_classifier_at(raw_point);
 
     find_preceding_boundary_display_point(map, point, FindRange::MultiLine, |left, right| {
         (classifier.kind(left) != classifier.kind(right) && !classifier.is_whitespace(right))
@@ -314,23 +314,23 @@ pub fn adjust_greedy_deletion(
     let is_backward = delete_from > delete_until;
     let delete_range = if is_backward {
         map.display_point_to_point(delete_until, Bias::Left)
-            .to_offset(&map.buffer_snapshot)
+            .to_offset(map.buffer_snapshot())
             ..map
                 .display_point_to_point(delete_from, Bias::Right)
-                .to_offset(&map.buffer_snapshot)
+                .to_offset(map.buffer_snapshot())
     } else {
         map.display_point_to_point(delete_from, Bias::Left)
-            .to_offset(&map.buffer_snapshot)
+            .to_offset(map.buffer_snapshot())
             ..map
                 .display_point_to_point(delete_until, Bias::Right)
-                .to_offset(&map.buffer_snapshot)
+                .to_offset(map.buffer_snapshot())
     };
 
     let trimmed_delete_range = if ignore_brackets {
         delete_range
     } else {
         let brackets_in_delete_range = map
-            .buffer_snapshot
+            .buffer_snapshot()
             .bracket_ranges(delete_range.clone())
             .into_iter()
             .flatten()
@@ -361,7 +361,7 @@ pub fn adjust_greedy_deletion(
     let mut whitespace_sequence_length = 0;
     let mut whitespace_sequence_start = 0;
     for ch in map
-        .buffer_snapshot
+        .buffer_snapshot()
         .text_for_range(trimmed_delete_range.clone())
         .flat_map(str::chars)
     {
@@ -405,7 +405,7 @@ pub fn adjust_greedy_deletion(
 /// lowerspace characters and uppercase characters.
 pub fn previous_subword_start(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint {
     let raw_point = point.to_point(map);
-    let classifier = map.buffer_snapshot.char_classifier_at(raw_point);
+    let classifier = map.buffer_snapshot().char_classifier_at(raw_point);
 
     find_preceding_boundary_display_point(map, point, FindRange::MultiLine, |left, right| {
         is_subword_start(left, right, &classifier) || left == '\n'
@@ -424,7 +424,7 @@ pub fn is_subword_start(left: char, right: char, classifier: &CharClassifier) ->
 /// uppercase letter, lowercase letter, '_' character or language-specific word character (like '-' in CSS).
 pub fn next_word_end(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint {
     let raw_point = point.to_point(map);
-    let classifier = map.buffer_snapshot.char_classifier_at(raw_point);
+    let classifier = map.buffer_snapshot().char_classifier_at(raw_point);
     let mut is_first_iteration = true;
     find_boundary(map, point, FindRange::MultiLine, |left, right| {
         // Make alt-right skip punctuation to respect VSCode behaviour. For example: |.hello goes to .hello|
@@ -447,7 +447,7 @@ pub fn next_word_end(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint
 /// uppercase letter, lowercase letter, '_' character, language-specific word character (like '-' in CSS) or newline.
 pub fn next_word_end_or_newline(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint {
     let raw_point = point.to_point(map);
-    let classifier = map.buffer_snapshot.char_classifier_at(raw_point);
+    let classifier = map.buffer_snapshot().char_classifier_at(raw_point);
 
     let mut on_starting_row = true;
     find_boundary(map, point, FindRange::MultiLine, |left, right| {
@@ -466,7 +466,7 @@ pub fn next_word_end_or_newline(map: &DisplaySnapshot, point: DisplayPoint) -> D
 /// lowerspace characters and uppercase characters.
 pub fn next_subword_end(map: &DisplaySnapshot, point: DisplayPoint) -> DisplayPoint {
     let raw_point = point.to_point(map);
-    let classifier = map.buffer_snapshot.char_classifier_at(raw_point);
+    let classifier = map.buffer_snapshot().char_classifier_at(raw_point);
 
     find_boundary(map, point, FindRange::MultiLine, |left, right| {
         is_subword_end(left, right, &classifier) || right == '\n'
@@ -496,7 +496,7 @@ pub fn start_of_paragraph(
 
     let mut found_non_blank_line = false;
     for row in (0..point.row + 1).rev() {
-        let blank = map.buffer_snapshot.is_line_blank(MultiBufferRow(row));
+        let blank = map.buffer_snapshot().is_line_blank(MultiBufferRow(row));
         if found_non_blank_line && blank {
             if count <= 1 {
                 return Point::new(row, 0).to_display_point(map);
@@ -519,13 +519,13 @@ pub fn end_of_paragraph(
     mut count: usize,
 ) -> DisplayPoint {
     let point = display_point.to_point(map);
-    if point.row == map.buffer_snapshot.max_row().0 {
+    if point.row == map.buffer_snapshot().max_row().0 {
         return map.max_point();
     }
 
     let mut found_non_blank_line = false;
-    for row in point.row..=map.buffer_snapshot.max_row().0 {
-        let blank = map.buffer_snapshot.is_line_blank(MultiBufferRow(row));
+    for row in point.row..=map.buffer_snapshot().max_row().0 {
+        let blank = map.buffer_snapshot().is_line_blank(MultiBufferRow(row));
         if found_non_blank_line && blank {
             if count <= 1 {
                 return Point::new(row, 0).to_display_point(map);
@@ -546,14 +546,14 @@ pub fn start_of_excerpt(
     direction: Direction,
 ) -> DisplayPoint {
     let point = map.display_point_to_point(display_point, Bias::Left);
-    let Some(excerpt) = map.buffer_snapshot.excerpt_containing(point..point) else {
+    let Some(excerpt) = map.buffer_snapshot().excerpt_containing(point..point) else {
         return display_point;
     };
     match direction {
         Direction::Prev => {
             let mut start = excerpt.start_anchor().to_display_point(map);
             if start >= display_point && start.row() > DisplayRow(0) {
-                let Some(excerpt) = map.buffer_snapshot.excerpt_before(excerpt.id()) else {
+                let Some(excerpt) = map.buffer_snapshot().excerpt_before(excerpt.id()) else {
                     return display_point;
                 };
                 start = excerpt.start_anchor().to_display_point(map);
@@ -574,7 +574,7 @@ pub fn end_of_excerpt(
     direction: Direction,
 ) -> DisplayPoint {
     let point = map.display_point_to_point(display_point, Bias::Left);
-    let Some(excerpt) = map.buffer_snapshot.excerpt_containing(point..point) else {
+    let Some(excerpt) = map.buffer_snapshot().excerpt_containing(point..point) else {
         return display_point;
     };
     match direction {
@@ -593,7 +593,9 @@ pub fn end_of_excerpt(
             if end <= display_point {
                 *end.row_mut() += 1;
                 let point_end = map.display_point_to_point(end, Bias::Right);
-                let Some(excerpt) = map.buffer_snapshot.excerpt_containing(point_end..point_end)
+                let Some(excerpt) = map
+                    .buffer_snapshot()
+                    .excerpt_containing(point_end..point_end)
                 else {
                     return display_point;
                 };
@@ -646,7 +648,7 @@ pub fn find_preceding_boundary_display_point(
     is_boundary: impl FnMut(char, char) -> bool,
 ) -> DisplayPoint {
     let result = find_preceding_boundary_point(
-        &map.buffer_snapshot,
+        map.buffer_snapshot(),
         from.to_point(map),
         find_range,
         is_boundary,
@@ -670,7 +672,7 @@ pub fn find_boundary_point(
     let mut prev_offset = offset;
     let mut prev_ch = None;
 
-    for ch in map.buffer_snapshot.chars_at(offset) {
+    for ch in map.buffer_snapshot().chars_at(offset) {
         if find_range == FindRange::SingleLine && ch == '\n' {
             break;
         }
@@ -698,8 +700,8 @@ pub fn find_preceding_boundary_trail(
     let mut offset = head.to_offset(map, Bias::Left);
     let mut trail_offset = None;
 
-    let mut prev_ch = map.buffer_snapshot.chars_at(offset).next();
-    let mut forward = map.buffer_snapshot.reversed_chars_at(offset).peekable();
+    let mut prev_ch = map.buffer_snapshot().chars_at(offset).next();
+    let mut forward = map.buffer_snapshot().reversed_chars_at(offset).peekable();
 
     // Skip newlines
     while let Some(&ch) = forward.peek() {
@@ -746,8 +748,8 @@ pub fn find_boundary_trail(
     let mut offset = head.to_offset(map, Bias::Right);
     let mut trail_offset = None;
 
-    let mut prev_ch = map.buffer_snapshot.reversed_chars_at(offset).next();
-    let mut forward = map.buffer_snapshot.chars_at(offset).peekable();
+    let mut prev_ch = map.buffer_snapshot().reversed_chars_at(offset).next();
+    let mut forward = map.buffer_snapshot().chars_at(offset).peekable();
 
     // Skip newlines
     while let Some(&ch) = forward.peek() {
@@ -810,7 +812,7 @@ pub fn chars_after(
     map: &DisplaySnapshot,
     mut offset: usize,
 ) -> impl Iterator<Item = (char, Range<usize>)> + '_ {
-    map.buffer_snapshot.chars_at(offset).map(move |ch| {
+    map.buffer_snapshot().chars_at(offset).map(move |ch| {
         let before = offset;
         offset += ch.len_utf8();
         (ch, before..offset)
@@ -824,7 +826,7 @@ pub fn chars_before(
     map: &DisplaySnapshot,
     mut offset: usize,
 ) -> impl Iterator<Item = (char, Range<usize>)> + '_ {
-    map.buffer_snapshot
+    map.buffer_snapshot()
         .reversed_chars_at(offset)
         .map(move |ch| {
             let after = offset;
@@ -1055,7 +1057,7 @@ mod tests {
                 |left, _| left == 'e',
             ),
             snapshot
-                .buffer_snapshot
+                .buffer_snapshot()
                 .offset_to_point(5)
                 .to_display_point(&snapshot),
             "Should not stop at inlays when looking for boundaries"

crates/editor/src/scroll.rs 🔗

@@ -251,7 +251,7 @@ impl ScrollManager {
                 Bias::Left,
             )
             .to_point(map);
-        let top_anchor = map.buffer_snapshot.anchor_after(scroll_top_buffer_point);
+        let top_anchor = map.buffer_snapshot().anchor_after(scroll_top_buffer_point);
 
         self.set_anchor(
             ScrollAnchor {
@@ -550,7 +550,7 @@ impl Editor {
         let snapshot = self.snapshot(window, cx).display_snapshot;
         let new_screen_top = DisplayPoint::new(row, 0);
         let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
-        let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
+        let new_anchor = snapshot.buffer_snapshot().anchor_before(new_screen_top);
 
         self.set_scroll_anchor(
             ScrollAnchor {

crates/editor/src/selections_collection.rs 🔗

@@ -225,13 +225,13 @@ impl SelectionsCollection {
         let map = self.display_map(cx);
         let start_ix = match self
             .disjoint
-            .binary_search_by(|probe| probe.end.cmp(&range.start, &map.buffer_snapshot))
+            .binary_search_by(|probe| probe.end.cmp(&range.start, map.buffer_snapshot()))
         {
             Ok(ix) | Err(ix) => ix,
         };
         let end_ix = match self
             .disjoint
-            .binary_search_by(|probe| probe.start.cmp(&range.end, &map.buffer_snapshot))
+            .binary_search_by(|probe| probe.start.cmp(&range.end, map.buffer_snapshot()))
         {
             Ok(ix) => ix + 1,
             Err(ix) => ix,
@@ -954,7 +954,7 @@ fn resolve_selections_point<'a>(
 ) -> impl 'a + Iterator<Item = Selection<Point>> {
     let (to_summarize, selections) = selections.into_iter().tee();
     let mut summaries = map
-        .buffer_snapshot
+        .buffer_snapshot()
         .summaries_for_anchors::<Point, _>(to_summarize.flat_map(|s| [&s.start, &s.end]))
         .into_iter();
     selections.map(move |s| {
@@ -1014,7 +1014,7 @@ where
 {
     let (to_convert, selections) = resolve_selections_display(selections, map).tee();
     let mut converted_endpoints =
-        map.buffer_snapshot
+        map.buffer_snapshot()
             .dimensions_from_points::<D>(to_convert.flat_map(|s| {
                 let start = map.display_point_to_point(s.start, Bias::Left);
                 let end = map.display_point_to_point(s.end, Bias::Right);

crates/editor/src/tasks.rs 🔗

@@ -28,12 +28,12 @@ impl Editor {
         let selection_range = selection.range();
         let start = editor_snapshot
             .display_snapshot
-            .buffer_snapshot
+            .buffer_snapshot()
             .anchor_after(selection_range.start)
             .text_anchor;
         let end = editor_snapshot
             .display_snapshot
-            .buffer_snapshot
+            .buffer_snapshot()
             .anchor_after(selection_range.end)
             .text_anchor;
         let location = Location {

crates/editor/src/test.rs 🔗

@@ -186,7 +186,7 @@ pub fn editor_content_with_blocks(editor: &Entity<Editor>, cx: &mut VisualTestCo
         match block {
             Block::Custom(custom_block) => {
                 if let BlockPlacement::Near(x) = &custom_block.placement
-                    && snapshot.intersects_fold(x.to_point(&snapshot.buffer_snapshot))
+                    && snapshot.intersects_fold(x.to_point(&snapshot.buffer_snapshot()))
                 {
                     continue;
                 };

crates/editor/src/test/editor_lsp_test_context.rs 🔗

@@ -303,8 +303,8 @@ impl EditorLspTestContext {
     #[expect(clippy::wrong_self_convention, reason = "This is test code")]
     pub fn to_lsp_range(&mut self, range: Range<usize>) -> lsp::Range {
         let snapshot = self.update_editor(|editor, window, cx| editor.snapshot(window, cx));
-        let start_point = range.start.to_point(&snapshot.buffer_snapshot);
-        let end_point = range.end.to_point(&snapshot.buffer_snapshot);
+        let start_point = range.start.to_point(&snapshot.buffer_snapshot());
+        let end_point = range.end.to_point(&snapshot.buffer_snapshot());
 
         self.editor(|editor, _, cx| {
             let buffer = editor.buffer().read(cx);
@@ -330,7 +330,7 @@ impl EditorLspTestContext {
     #[expect(clippy::wrong_self_convention, reason = "This is test code")]
     pub fn to_lsp(&mut self, offset: usize) -> lsp::Position {
         let snapshot = self.update_editor(|editor, window, cx| editor.snapshot(window, cx));
-        let point = offset.to_point(&snapshot.buffer_snapshot);
+        let point = offset.to_point(&snapshot.buffer_snapshot());
 
         self.editor(|editor, _, cx| {
             let buffer = editor.buffer().read(cx);

crates/editor/src/test/editor_test_context.rs 🔗

@@ -504,7 +504,7 @@ impl EditorTestContext {
                 .map(|h| h.1.clone())
                 .unwrap_or_default()
                 .iter()
-                .map(|range| range.to_offset(&snapshot.buffer_snapshot))
+                .map(|range| range.to_offset(&snapshot.buffer_snapshot()))
                 .collect()
         });
         assert_set_eq!(actual_ranges, expected_ranges);
@@ -519,7 +519,7 @@ impl EditorTestContext {
             .map(|ranges| ranges.as_ref().clone().1)
             .unwrap_or_default()
             .into_iter()
-            .map(|range| range.to_offset(&snapshot.buffer_snapshot))
+            .map(|range| range.to_offset(&snapshot.buffer_snapshot()))
             .collect();
         assert_set_eq!(actual_ranges, expected_ranges);
     }
@@ -579,7 +579,7 @@ pub fn assert_state_with_diff(
 ) {
     let (snapshot, selections) = editor.update_in(cx, |editor, window, cx| {
         (
-            editor.snapshot(window, cx).buffer_snapshot.clone(),
+            editor.snapshot(window, cx).buffer_snapshot().clone(),
             editor.selections.ranges::<usize>(cx),
         )
     });

crates/git_ui/src/project_diff.rs 🔗

@@ -1557,7 +1557,7 @@ mod tests {
         let prev_buffer_hunks =
             cx.update_window_entity(&buffer_editor, |buffer_editor, window, cx| {
                 let snapshot = buffer_editor.snapshot(window, cx);
-                let snapshot = &snapshot.buffer_snapshot;
+                let snapshot = &snapshot.buffer_snapshot();
                 let prev_buffer_hunks = buffer_editor
                     .diff_hunks_in_ranges(&[editor::Anchor::min()..editor::Anchor::max()], snapshot)
                     .collect::<Vec<_>>();
@@ -1570,7 +1570,7 @@ mod tests {
         let new_buffer_hunks =
             cx.update_window_entity(&buffer_editor, |buffer_editor, window, cx| {
                 let snapshot = buffer_editor.snapshot(window, cx);
-                let snapshot = &snapshot.buffer_snapshot;
+                let snapshot = &snapshot.buffer_snapshot();
                 buffer_editor
                     .diff_hunks_in_ranges(&[editor::Anchor::min()..editor::Anchor::max()], snapshot)
                     .collect::<Vec<_>>()

crates/language_tools/src/syntax_tree_view.rs 🔗

@@ -255,7 +255,7 @@ impl SyntaxTreeView {
             let selection_range = editor.selections.last::<usize>(cx).range();
             let multi_buffer = editor.buffer().read(cx);
             let (buffer, range, excerpt_id) = snapshot
-                .buffer_snapshot
+                .buffer_snapshot()
                 .range_to_buffer_ranges(selection_range)
                 .pop()?;
             let buffer = multi_buffer.buffer(buffer.remote_id()).unwrap();

crates/vim/src/command.rs 🔗

@@ -602,7 +602,7 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
             let buffer_row = action.range.head().buffer_row(vim, editor, window, cx)?;
             let current = editor.selections.newest::<Point>(cx);
             let target = snapshot
-                .buffer_snapshot
+                .buffer_snapshot()
                 .clip_point(Point::new(buffer_row.0, current.head().column), Bias::Left);
             editor.change_selections(Default::default(), window, cx, |s| {
                 s.select_ranges([target..target]);
@@ -624,10 +624,10 @@ pub fn register(editor: &mut Editor, cx: &mut Context<Vim>) {
         vim.update_editor(cx, |vim, editor, cx| {
             let snapshot = editor.snapshot(window, cx);
             if let Ok(range) = action.range.buffer_range(vim, editor, window, cx) {
-                let end = if range.end < snapshot.buffer_snapshot.max_row() {
+                let end = if range.end < snapshot.buffer_snapshot().max_row() {
                     Point::new(range.end.0 + 1, 0)
                 } else {
-                    snapshot.buffer_snapshot.max_point()
+                    snapshot.buffer_snapshot().max_point()
                 };
                 vim.copy_ranges(
                     editor,
@@ -963,7 +963,7 @@ impl Position {
                     )
                 }) {
                     anchor
-                        .to_point(&snapshot.buffer_snapshot)
+                        .to_point(&snapshot.buffer_snapshot())
                         .row
                         .saturating_add_signed(*offset)
                 } else {
@@ -979,12 +979,12 @@ impl Position {
                 let Some(mark) = anchors.last() else {
                     anyhow::bail!("mark {name} contains empty anchors");
                 };
-                mark.to_point(&snapshot.buffer_snapshot)
+                mark.to_point(&snapshot.buffer_snapshot())
                     .row
                     .saturating_add_signed(*offset)
             }
             Position::LastLine { offset } => snapshot
-                .buffer_snapshot
+                .buffer_snapshot()
                 .max_row()
                 .0
                 .saturating_add_signed(*offset),
@@ -992,12 +992,12 @@ impl Position {
                 .selections
                 .newest_anchor()
                 .head()
-                .to_point(&snapshot.buffer_snapshot)
+                .to_point(&snapshot.buffer_snapshot())
                 .row
                 .saturating_add_signed(*offset),
         };
 
-        Ok(MultiBufferRow(target).min(snapshot.buffer_snapshot.max_row()))
+        Ok(MultiBufferRow(target).min(snapshot.buffer_snapshot().max_row()))
     }
 }
 
@@ -1652,7 +1652,7 @@ impl OnMatchingLines {
 
             let point_range = Point::new(range.start.0, 0)
                 ..snapshot
-                    .buffer_snapshot
+                    .buffer_snapshot()
                     .clip_point(Point::new(range.end.0 + 1, 0), Bias::Left);
             cx.spawn_in(window, async move |editor, cx| {
                 let new_selections = cx
@@ -1660,7 +1660,7 @@ impl OnMatchingLines {
                         let mut line = String::new();
                         let mut new_selections = Vec::new();
                         let chunks = snapshot
-                            .buffer_snapshot
+                            .buffer_snapshot()
                             .text_for_range(point_range)
                             .chain(["\n"]);
 

crates/vim/src/helix.rs 🔗

@@ -133,7 +133,7 @@ impl Vim {
         self.helix_new_selections(window, cx, |cursor, map| {
             let mut head = movement::right(map, cursor);
             let mut tail = cursor;
-            let classifier = map.buffer_snapshot.char_classifier_at(head.to_point(map));
+            let classifier = map.buffer_snapshot().char_classifier_at(head.to_point(map));
             if head == map.max_point() {
                 return None;
             }
@@ -170,7 +170,7 @@ impl Vim {
             // but the search starts from the left side of it,
             // so to include that space the selection must end one character to the right.
             let mut tail = movement::right(map, cursor);
-            let classifier = map.buffer_snapshot.char_classifier_at(head.to_point(map));
+            let classifier = map.buffer_snapshot().char_classifier_at(head.to_point(map));
             if head == DisplayPoint::zero() {
                 return None;
             }
@@ -467,7 +467,7 @@ impl Vim {
                         let was_empty = range.is_empty();
                         let was_reversed = selection.reversed;
                         (
-                            map.buffer_snapshot.anchor_before(start_offset),
+                            map.buffer_snapshot().anchor_before(start_offset),
                             end_offset - start_offset,
                             was_empty,
                             was_reversed,
@@ -546,8 +546,8 @@ impl Vim {
             editor.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
             let display_map = editor.display_map.update(cx, |map, cx| map.snapshot(cx));
             let mut selections = editor.selections.all::<Point>(cx);
-            let max_point = display_map.buffer_snapshot.max_point();
-            let buffer_snapshot = &display_map.buffer_snapshot;
+            let max_point = display_map.buffer_snapshot().max_point();
+            let buffer_snapshot = &display_map.buffer_snapshot();
 
             for selection in &mut selections {
                 // Start always goes to column 0 of the first selected line

crates/vim/src/helix/boundary.rs 🔗

@@ -166,14 +166,16 @@ impl DerefMut for Offset {
 }
 impl Offset {
     fn next(self, map: &DisplaySnapshot) -> Option<Self> {
-        let next = Self(map.buffer_snapshot.clip_offset(*self + 1, Bias::Right));
+        let next = Self(map.buffer_snapshot().clip_offset(*self + 1, Bias::Right));
         (*next > *self).then(|| next)
     }
     fn previous(self, map: &DisplaySnapshot) -> Option<Self> {
         if *self == 0 {
             return None;
         }
-        Some(Self(map.buffer_snapshot.clip_offset(*self - 1, Bias::Left)))
+        Some(Self(
+            map.buffer_snapshot().clip_offset(*self - 1, Bias::Left),
+        ))
     }
     fn range(
         start: (DisplayPoint, Bias),
@@ -388,7 +390,7 @@ impl ImmediateBoundary {
 impl BoundedObject for ImmediateBoundary {
     fn next_start(&self, map: &DisplaySnapshot, from: Offset, outer: bool) -> Option<Offset> {
         try_find_boundary(map, from, |left, right| {
-            let classifier = map.buffer_snapshot.char_classifier_at(*from);
+            let classifier = map.buffer_snapshot().char_classifier_at(*from);
             if outer {
                 self.is_outer_start(left, right, classifier)
             } else {
@@ -398,7 +400,7 @@ impl BoundedObject for ImmediateBoundary {
     }
     fn next_end(&self, map: &DisplaySnapshot, from: Offset, outer: bool) -> Option<Offset> {
         try_find_boundary(map, from, |left, right| {
-            let classifier = map.buffer_snapshot.char_classifier_at(*from);
+            let classifier = map.buffer_snapshot().char_classifier_at(*from);
             if outer {
                 self.is_outer_end(left, right, classifier)
             } else {
@@ -408,7 +410,7 @@ impl BoundedObject for ImmediateBoundary {
     }
     fn previous_start(&self, map: &DisplaySnapshot, from: Offset, outer: bool) -> Option<Offset> {
         try_find_preceding_boundary(map, from, |left, right| {
-            let classifier = map.buffer_snapshot.char_classifier_at(*from);
+            let classifier = map.buffer_snapshot().char_classifier_at(*from);
             if outer {
                 self.is_outer_start(left, right, classifier)
             } else {
@@ -418,7 +420,7 @@ impl BoundedObject for ImmediateBoundary {
     }
     fn previous_end(&self, map: &DisplaySnapshot, from: Offset, outer: bool) -> Option<Offset> {
         try_find_preceding_boundary(map, from, |left, right| {
-            let classifier = map.buffer_snapshot.char_classifier_at(*from);
+            let classifier = map.buffer_snapshot().char_classifier_at(*from);
             if outer {
                 self.is_outer_end(left, right, classifier)
             } else {
@@ -570,7 +572,7 @@ impl FuzzyBoundary {
         boundary_kind: Boundary,
     ) -> Option<Offset> {
         let generate_boundary_data = |left, right, point: Offset| {
-            let classifier = map.buffer_snapshot.char_classifier_at(*from);
+            let classifier = map.buffer_snapshot().char_classifier_at(*from);
             let reach_boundary = if outer && boundary_kind == Boundary::Start {
                 self.is_near_potential_outer_start(left, right, &classifier)
             } else if !outer && boundary_kind == Boundary::Start {
@@ -659,12 +661,12 @@ fn try_find_boundary_data<T>(
     boundary_information: impl Fn(char, char, Offset) -> Option<T>,
 ) -> Option<T> {
     let mut prev_ch = map
-        .buffer_snapshot
+        .buffer_snapshot()
         .reversed_chars_at(*from)
         .next()
         .unwrap_or('\0');
 
-    for ch in map.buffer_snapshot.chars_at(*from).chain(['\0']) {
+    for ch in map.buffer_snapshot().chars_at(*from).chain(['\0']) {
         if let Some(boundary_information) = boundary_information(prev_ch, ch, from) {
             return Some(boundary_information);
         }
@@ -700,9 +702,9 @@ fn try_find_preceding_boundary_data<T>(
     mut from: Offset,
     is_boundary: impl Fn(char, char, Offset) -> Option<T>,
 ) -> Option<T> {
-    let mut prev_ch = map.buffer_snapshot.chars_at(*from).next().unwrap_or('\0');
+    let mut prev_ch = map.buffer_snapshot().chars_at(*from).next().unwrap_or('\0');
 
-    for ch in map.buffer_snapshot.reversed_chars_at(*from).chain(['\0']) {
+    for ch in map.buffer_snapshot().reversed_chars_at(*from).chain(['\0']) {
         if let Some(boundary_information) = is_boundary(ch, prev_ch, from) {
             return Some(boundary_information);
         }

crates/vim/src/helix/paste.rs 🔗

@@ -109,9 +109,9 @@ impl Vim {
                     };
                     let point = display_point.to_point(&display_map);
                     let anchor = if action.before {
-                        display_map.buffer_snapshot.anchor_after(point)
+                        display_map.buffer_snapshot().anchor_after(point)
                     } else {
-                        display_map.buffer_snapshot.anchor_before(point)
+                        display_map.buffer_snapshot().anchor_before(point)
                     };
                     edits.push((point..point, to_insert.repeat(count)));
                     new_selections.push((anchor, to_insert.len() * count));

crates/vim/src/motion.rs 🔗

@@ -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);

crates/vim/src/normal/change.rs 🔗

@@ -69,7 +69,7 @@ impl Vim {
                                     let mut start_offset =
                                         selection.start.to_offset(map, Bias::Left);
                                     let classifier = map
-                                        .buffer_snapshot
+                                        .buffer_snapshot()
                                         .char_classifier_at(selection.start.to_point(map));
                                     for (ch, offset) in map.buffer_chars_at(start_offset) {
                                         if ch == '\n' || !classifier.is_whitespace(ch) {
@@ -153,7 +153,7 @@ fn expand_changed_word_selection(
 ) -> Option<MotionKind> {
     let is_in_word = || {
         let classifier = map
-            .buffer_snapshot
+            .buffer_snapshot()
             .char_classifier_at(selection.start.to_point(map));
 
         map.buffer_chars_at(selection.head().to_offset(map, Bias::Left))

crates/vim/src/normal/delete.rs 🔗

@@ -50,12 +50,13 @@ impl Vim {
                         if kind == Some(MotionKind::Linewise) {
                             let start = selection.start.to_point(map);
                             let end = selection.end.to_point(map);
-                            if end.row < map.buffer_snapshot.max_point().row {
+                            if end.row < map.buffer_snapshot().max_point().row {
                                 selection.end = Point::new(end.row + 1, 0).to_display_point(map)
                             } else if start.row > 0 {
                                 selection.start = Point::new(
                                     start.row - 1,
-                                    map.buffer_snapshot.line_len(MultiBufferRow(start.row - 1)),
+                                    map.buffer_snapshot()
+                                        .line_len(MultiBufferRow(start.row - 1)),
                                 )
                                 .to_display_point(map)
                             }
@@ -183,7 +184,7 @@ impl Vim {
                             let mut cursor_point = cursor.to_point(map);
                             cursor_point.column = *column;
                             cursor = map
-                                .buffer_snapshot
+                                .buffer_snapshot()
                                 .clip_point(cursor_point, Bias::Left)
                                 .to_display_point(map);
                         }
@@ -203,7 +204,7 @@ fn move_selection_end_to_next_line(map: &DisplaySnapshot, selection: &mut Select
 }
 
 fn ends_at_eof(map: &DisplaySnapshot, selection: &mut Selection<DisplayPoint>) -> bool {
-    selection.end.to_point(map) == map.buffer_snapshot.max_point()
+    selection.end.to_point(map) == map.buffer_snapshot().max_point()
 }
 
 #[cfg(test)]

crates/vim/src/normal/mark.rs 🔗

@@ -54,11 +54,11 @@ impl Vim {
             for selection in selections {
                 let end = movement::saturating_left(&map, selection.end);
                 ends.push(
-                    map.buffer_snapshot
+                    map.buffer_snapshot()
                         .anchor_before(end.to_offset(&map, Bias::Left)),
                 );
                 starts.push(
-                    map.buffer_snapshot
+                    map.buffer_snapshot()
                         .anchor_before(selection.start.to_offset(&map, Bias::Left)),
                 );
                 reversed.push(selection.reversed)
@@ -106,7 +106,7 @@ impl Vim {
                         point = motion::first_non_whitespace(&map.display_snapshot, false, point);
                         anchor = map
                             .display_snapshot
-                            .buffer_snapshot
+                            .buffer_snapshot()
                             .anchor_before(point.to_point(&map.display_snapshot));
                     }
 
@@ -239,7 +239,7 @@ impl Vim {
                         point = motion::first_non_whitespace(&map.display_snapshot, false, point);
                         anchor = map
                             .display_snapshot
-                            .buffer_snapshot
+                            .buffer_snapshot()
                             .anchor_before(point.to_point(&map.display_snapshot));
                     }
 
@@ -312,7 +312,7 @@ impl Vim {
                         ")" => motion::sentence_forwards(&map, selection.head(), 1),
                         _ => unreachable!(),
                     };
-                    map.buffer_snapshot
+                    map.buffer_snapshot()
                         .anchor_before(point.to_offset(&map, Bias::Left))
                 })
                 .collect::<Vec<Anchor>>();

crates/vim/src/normal/paste.rs 🔗

@@ -159,9 +159,11 @@ impl Vim {
                     let point_range = display_range.start.to_point(&display_map)
                         ..display_range.end.to_point(&display_map);
                     let anchor = if is_multiline || vim.mode == Mode::VisualLine {
-                        display_map.buffer_snapshot.anchor_before(point_range.start)
+                        display_map
+                            .buffer_snapshot()
+                            .anchor_before(point_range.start)
                     } else {
-                        display_map.buffer_snapshot.anchor_after(point_range.end)
+                        display_map.buffer_snapshot().anchor_after(point_range.end)
                     };
 
                     if *preserve {

crates/vim/src/normal/search.rs 🔗

@@ -263,7 +263,7 @@ impl Vim {
         if prior_selections.iter().any(|s| {
             self.update_editor(cx, |_, editor, cx| {
                 !s.start
-                    .is_valid(&editor.snapshot(window, cx).buffer_snapshot)
+                    .is_valid(&editor.snapshot(window, cx).buffer_snapshot())
             })
             .unwrap_or(true)
         }) {
@@ -469,7 +469,8 @@ impl Vim {
         };
         if let Some(result) = self.update_editor(cx, |vim, editor, cx| {
             let range = action.range.buffer_range(vim, editor, window, cx)?;
-            let snapshot = &editor.snapshot(window, cx).buffer_snapshot;
+            let snapshot = editor.snapshot(window, cx);
+            let snapshot = snapshot.buffer_snapshot();
             let end_point = Point::new(range.end.0, snapshot.line_len(range.end));
             let range = snapshot.anchor_before(Point::new(range.start.0, 0))
                 ..snapshot.anchor_after(end_point);

crates/vim/src/object.rs 🔗

@@ -94,7 +94,7 @@ fn cover_or_next<I: Iterator<Item = (Range<usize>, Range<usize>)>>(
     let caret_offset = caret.to_offset(map, Bias::Left);
     let mut covering = vec![];
     let mut next_ones = vec![];
-    let snapshot = &map.buffer_snapshot;
+    let snapshot = &map.buffer_snapshot();
 
     if let Some(ranges) = candidates {
         for (open_range, close_range) in ranges {
@@ -173,12 +173,12 @@ fn find_mini_delimiters(
     is_valid_delimiter: &DelimiterPredicate,
 ) -> Option<Range<DisplayPoint>> {
     let point = map.clip_at_line_end(display_point).to_point(map);
-    let offset = point.to_offset(&map.buffer_snapshot);
+    let offset = point.to_offset(&map.buffer_snapshot());
 
     let line_range = get_line_range(map, point);
     let visible_line_range = get_visible_line_range(&line_range);
 
-    let snapshot = &map.buffer_snapshot;
+    let snapshot = &map.buffer_snapshot();
     let excerpt = snapshot.excerpt_containing(offset..offset)?;
     let buffer = excerpt.buffer();
 
@@ -187,7 +187,7 @@ fn find_mini_delimiters(
     };
 
     // Try to find delimiters in visible range first
-    let ranges = map.buffer_snapshot.bracket_ranges(visible_line_range);
+    let ranges = map.buffer_snapshot().bracket_ranges(visible_line_range);
     if let Some(candidate) = cover_or_next(ranges, display_point, map, Some(&bracket_filter)) {
         return Some(
             DelimiterRange {
@@ -740,7 +740,7 @@ fn in_word(
 ) -> Option<Range<DisplayPoint>> {
     // Use motion::right so that we consider the character under the cursor when looking for the start
     let classifier = map
-        .buffer_snapshot
+        .buffer_snapshot()
         .char_classifier_at(relative_to.to_point(map))
         .ignore_punctuation(ignore_punctuation);
     let start = movement::find_preceding_boundary_display_point(
@@ -765,7 +765,7 @@ fn in_subword(
     let offset = relative_to.to_offset(map, Bias::Left);
     // Use motion::right so that we consider the character under the cursor when looking for the start
     let classifier = map
-        .buffer_snapshot
+        .buffer_snapshot()
         .char_classifier_at(relative_to.to_point(map))
         .ignore_punctuation(ignore_punctuation);
     let in_subword = map
@@ -838,7 +838,7 @@ pub fn surrounding_html_tag(
         Some(read_tag(chars))
     }
 
-    let snapshot = &map.buffer_snapshot;
+    let snapshot = &map.buffer_snapshot();
     let offset = head.to_offset(map, Bias::Left);
     let mut excerpt = snapshot.excerpt_containing(offset..offset)?;
     let buffer = excerpt.buffer();
@@ -909,7 +909,7 @@ fn around_word(
 ) -> Option<Range<DisplayPoint>> {
     let offset = relative_to.to_offset(map, Bias::Left);
     let classifier = map
-        .buffer_snapshot
+        .buffer_snapshot()
         .char_classifier_at(offset)
         .ignore_punctuation(ignore_punctuation);
     let in_word = map
@@ -932,7 +932,7 @@ fn around_subword(
 ) -> Option<Range<DisplayPoint>> {
     // Use motion::right so that we consider the character under the cursor when looking for the start
     let classifier = map
-        .buffer_snapshot
+        .buffer_snapshot()
         .char_classifier_at(relative_to.to_point(map))
         .ignore_punctuation(ignore_punctuation);
     let start = movement::find_preceding_boundary_display_point(
@@ -991,7 +991,7 @@ fn around_next_word(
     ignore_punctuation: bool,
 ) -> Option<Range<DisplayPoint>> {
     let classifier = map
-        .buffer_snapshot
+        .buffer_snapshot()
         .char_classifier_at(relative_to.to_point(map))
         .ignore_punctuation(ignore_punctuation);
     // Get the start of the word
@@ -1028,7 +1028,7 @@ fn text_object(
     relative_to: DisplayPoint,
     target: TextObject,
 ) -> Option<Range<DisplayPoint>> {
-    let snapshot = &map.buffer_snapshot;
+    let snapshot = &map.buffer_snapshot();
     let offset = relative_to.to_offset(map, Bias::Left);
 
     let mut excerpt = snapshot.excerpt_containing(offset..offset)?;
@@ -1073,7 +1073,7 @@ fn argument(
     relative_to: DisplayPoint,
     around: bool,
 ) -> Option<Range<DisplayPoint>> {
-    let snapshot = &map.buffer_snapshot;
+    let snapshot = &map.buffer_snapshot();
     let offset = relative_to.to_offset(map, Bias::Left);
 
     // The `argument` vim text object uses the syntax tree, so we operate at the buffer level and map back to the display level
@@ -1247,7 +1247,7 @@ fn indent(
 
     // Loop forwards until we find a non-blank line with less indent
     let mut end_row = row;
-    let max_rows = map.buffer_snapshot.max_row().0;
+    let max_rows = map.buffer_snapshot().max_row().0;
     for next_row in (row + 1)..=max_rows {
         let indent = map.line_indent_for_buffer_row(MultiBufferRow(next_row));
         if indent.is_line_empty() {
@@ -1263,7 +1263,7 @@ fn indent(
         end_row = next_row;
     }
 
-    let end_len = map.buffer_snapshot.line_len(MultiBufferRow(end_row));
+    let end_len = map.buffer_snapshot().line_len(MultiBufferRow(end_row));
     let start = map.point_to_display_point(Point::new(start_row, 0), Bias::Right);
     let end = map.point_to_display_point(Point::new(end_row, end_len), Bias::Left);
     Some(start..end)
@@ -1434,7 +1434,9 @@ fn paragraph(
         let paragraph_end_row = paragraph_end.row();
         let paragraph_ends_with_eof = paragraph_end_row == map.max_point().row();
         let point = relative_to.to_point(map);
-        let current_line_is_empty = map.buffer_snapshot.is_line_blank(MultiBufferRow(point.row));
+        let current_line_is_empty = map
+            .buffer_snapshot()
+            .is_line_blank(MultiBufferRow(point.row));
 
         if around {
             if paragraph_ends_with_eof {
@@ -1472,10 +1474,12 @@ pub fn start_of_paragraph(map: &DisplaySnapshot, display_point: DisplayPoint) ->
         return DisplayPoint::zero();
     }
 
-    let is_current_line_blank = map.buffer_snapshot.is_line_blank(MultiBufferRow(point.row));
+    let is_current_line_blank = map
+        .buffer_snapshot()
+        .is_line_blank(MultiBufferRow(point.row));
 
     for row in (0..point.row).rev() {
-        let blank = map.buffer_snapshot.is_line_blank(MultiBufferRow(row));
+        let blank = map.buffer_snapshot().is_line_blank(MultiBufferRow(row));
         if blank != is_current_line_blank {
             return Point::new(row + 1, 0).to_display_point(map);
         }
@@ -1489,19 +1493,21 @@ pub fn start_of_paragraph(map: &DisplaySnapshot, display_point: DisplayPoint) ->
 /// The trailing newline is excluded from the paragraph.
 pub fn end_of_paragraph(map: &DisplaySnapshot, display_point: DisplayPoint) -> DisplayPoint {
     let point = display_point.to_point(map);
-    if point.row == map.buffer_snapshot.max_row().0 {
+    if point.row == map.buffer_snapshot().max_row().0 {
         return map.max_point();
     }
 
-    let is_current_line_blank = map.buffer_snapshot.is_line_blank(MultiBufferRow(point.row));
+    let is_current_line_blank = map
+        .buffer_snapshot()
+        .is_line_blank(MultiBufferRow(point.row));
 
-    for row in point.row + 1..map.buffer_snapshot.max_row().0 + 1 {
-        let blank = map.buffer_snapshot.is_line_blank(MultiBufferRow(row));
+    for row in point.row + 1..map.buffer_snapshot().max_row().0 + 1 {
+        let blank = map.buffer_snapshot().is_line_blank(MultiBufferRow(row));
         if blank != is_current_line_blank {
             let previous_row = row - 1;
             return Point::new(
                 previous_row,
-                map.buffer_snapshot.line_len(MultiBufferRow(previous_row)),
+                map.buffer_snapshot().line_len(MultiBufferRow(previous_row)),
             )
             .to_display_point(map);
         }

crates/vim/src/replace.rs 🔗

@@ -65,12 +65,12 @@ impl Vim {
                         // we don't do a replace, we need insert a "\n"
                         if !is_new_line {
                             range.end.column += 1;
-                            range.end = map.buffer_snapshot.clip_point(range.end, Bias::Right);
+                            range.end = map.buffer_snapshot().clip_point(range.end, Bias::Right);
                         }
-                        let replace_range = map.buffer_snapshot.anchor_before(range.start)
-                            ..map.buffer_snapshot.anchor_after(range.end);
+                        let replace_range = map.buffer_snapshot().anchor_before(range.start)
+                            ..map.buffer_snapshot().anchor_after(range.end);
                         let current_text = map
-                            .buffer_snapshot
+                            .buffer_snapshot()
                             .text_for_range(replace_range.clone())
                             .collect();
                         vim.replacements.push((replace_range.clone(), current_text));
@@ -111,15 +111,15 @@ impl Vim {
                         )
                         .to_point(&map);
                         new_selections.push(
-                            map.buffer_snapshot.anchor_before(start)
-                                ..map.buffer_snapshot.anchor_before(start),
+                            map.buffer_snapshot().anchor_before(start)
+                                ..map.buffer_snapshot().anchor_before(start),
                         );
 
                         let mut undo = None;
                         let edit_range = start..end;
                         for (i, (range, inverse)) in vim.replacements.iter().rev().enumerate() {
-                            if range.start.to_point(&map.buffer_snapshot) <= edit_range.start
-                                && range.end.to_point(&map.buffer_snapshot) >= edit_range.end
+                            if range.start.to_point(&map.buffer_snapshot()) <= edit_range.start
+                                && range.end.to_point(&map.buffer_snapshot()) >= edit_range.end
                             {
                                 undo = Some(inverse.clone());
                                 vim.replacements.remove(vim.replacements.len() - i - 1);
@@ -154,10 +154,10 @@ impl Vim {
             let snapshot = editor.snapshot(window, cx);
             object.expand_selection(&snapshot, &mut selection, around, None);
             let start = snapshot
-                .buffer_snapshot
+                .buffer_snapshot()
                 .anchor_before(selection.start.to_point(&snapshot));
             let end = snapshot
-                .buffer_snapshot
+                .buffer_snapshot()
                 .anchor_before(selection.end.to_point(&snapshot));
             let new_range = start..end;
             vim.exchange_impl(new_range, editor, &snapshot, window, cx);
@@ -206,10 +206,10 @@ impl Vim {
                 forced_motion,
             );
             let start = snapshot
-                .buffer_snapshot
+                .buffer_snapshot()
                 .anchor_before(selection.start.to_point(&snapshot));
             let end = snapshot
-                .buffer_snapshot
+                .buffer_snapshot()
                 .anchor_before(selection.end.to_point(&snapshot));
             let new_range = start..end;
             vim.exchange_impl(new_range, editor, &snapshot, window, cx);
@@ -228,14 +228,14 @@ impl Vim {
         if let Some((_, ranges)) = editor.clear_background_highlights::<VimExchange>(cx) {
             let previous_range = ranges[0].clone();
 
-            let new_range_start = new_range.start.to_offset(&snapshot.buffer_snapshot);
-            let new_range_end = new_range.end.to_offset(&snapshot.buffer_snapshot);
-            let previous_range_end = previous_range.end.to_offset(&snapshot.buffer_snapshot);
-            let previous_range_start = previous_range.start.to_offset(&snapshot.buffer_snapshot);
+            let new_range_start = new_range.start.to_offset(&snapshot.buffer_snapshot());
+            let new_range_end = new_range.end.to_offset(&snapshot.buffer_snapshot());
+            let previous_range_end = previous_range.end.to_offset(&snapshot.buffer_snapshot());
+            let previous_range_start = previous_range.start.to_offset(&snapshot.buffer_snapshot());
 
             let text_for = |range: Range<Anchor>| {
                 snapshot
-                    .buffer_snapshot
+                    .buffer_snapshot()
                     .text_for_range(range)
                     .collect::<String>()
             };

crates/vim/src/surrounds.rs 🔗

@@ -94,14 +94,14 @@ impl Vim {
                                 format!("{}{}", maybe_space, pair.end),
                             )
                         };
-                        let start_anchor = display_map.buffer_snapshot.anchor_before(start);
+                        let start_anchor = display_map.buffer_snapshot().anchor_before(start);
 
                         edits.push((start..start, start_cursor_str));
                         edits.push((end..end, end_cursor_str));
                         anchors.push(start_anchor..start_anchor);
                     } else {
                         let start_anchor = display_map
-                            .buffer_snapshot
+                            .buffer_snapshot()
                             .anchor_before(selection.head().to_offset(&display_map, Bias::Left));
                         anchors.push(start_anchor..start_anchor);
                     }
@@ -323,7 +323,7 @@ impl Vim {
                         .disjoint_anchors_arc()
                         .iter()
                         .map(|selection| {
-                            let start = selection.start.bias_left(&display_map.buffer_snapshot);
+                            let start = selection.start.bias_left(&display_map.buffer_snapshot());
                             start..start
                         })
                         .collect::<Vec<_>>();

crates/vim/src/test.rs 🔗

@@ -902,7 +902,7 @@ fn assert_pending_input(cx: &mut VimTestContext, expected: &str) {
         assert_eq!(
             highlights
                 .iter()
-                .map(|highlight| highlight.to_offset(&snapshot.buffer_snapshot))
+                .map(|highlight| highlight.to_offset(&snapshot.buffer_snapshot()))
                 .collect::<Vec<_>>(),
             ranges
         )
@@ -962,7 +962,7 @@ async fn test_jk_delay(cx: &mut gpui::TestAppContext) {
         assert_eq!(
             highlights
                 .iter()
-                .map(|highlight| highlight.to_offset(&snapshot.buffer_snapshot))
+                .map(|highlight| highlight.to_offset(&snapshot.buffer_snapshot()))
                 .collect::<Vec<_>>(),
             vec![0..1]
         )

crates/vim/src/vim.rs 🔗

@@ -1142,11 +1142,11 @@ impl Vim {
                     && mode.is_visual()
                     && !last_mode.is_visual()
                 {
-                    let mut end = pending.end.to_point(&snapshot.buffer_snapshot);
+                    let mut end = pending.end.to_point(&snapshot.buffer_snapshot());
                     end = snapshot
-                        .buffer_snapshot
+                        .buffer_snapshot()
                         .clip_point(end + Point::new(0, 1), Bias::Right);
-                    pending.end = snapshot.buffer_snapshot.anchor_before(end);
+                    pending.end = snapshot.buffer_snapshot().anchor_before(end);
                 }
 
                 s.move_with(|map, selection| {
@@ -1412,7 +1412,8 @@ impl Vim {
         self.update_editor(cx, |_, editor, cx| {
             let selection = editor.selections.newest::<usize>(cx);
 
-            let snapshot = &editor.snapshot(window, cx).buffer_snapshot;
+            let snapshot = editor.snapshot(window, cx);
+            let snapshot = snapshot.buffer_snapshot();
             let (range, kind) =
                 snapshot.surrounding_word(selection.start, Some(CharScopeContext::Completion));
             if kind == Some(CharKind::Word) {

crates/vim/src/visual.rs 🔗

@@ -485,7 +485,7 @@ impl Vim {
                             if object == Object::Paragraph && range.start != range.end {
                                 let row_of_selection_end_line = selection.end.to_point(map).row;
                                 let new_selection_end = if map
-                                    .buffer_snapshot
+                                    .buffer_snapshot()
                                     .line_len(MultiBufferRow(row_of_selection_end_line))
                                     == 0
                                 {
@@ -505,7 +505,7 @@ impl Vim {
                                     if selection.end.to_point(map).row > new_start_point.row {
                                         if original_point.column
                                             == map
-                                                .buffer_snapshot
+                                                .buffer_snapshot()
                                                 .line_len(MultiBufferRow(original_point.row))
                                         {
                                             selection.start = movement::saturating_left(
@@ -635,7 +635,7 @@ impl Vim {
                                     let row = end.row.saturating_sub(1);
                                     selection.end = Point::new(
                                         row,
-                                        map.buffer_snapshot.line_len(MultiBufferRow(row)),
+                                        map.buffer_snapshot().line_len(MultiBufferRow(row)),
                                     )
                                     .to_display_point(map)
                                 } else {
@@ -658,12 +658,13 @@ impl Vim {
                         s.move_with(|map, selection| {
                             let end = selection.end.to_point(map);
                             let start = selection.start.to_point(map);
-                            if end.row < map.buffer_snapshot.max_point().row {
+                            if end.row < map.buffer_snapshot().max_point().row {
                                 selection.end = Point::new(end.row + 1, 0).to_display_point(map)
                             } else if start.row > 0 {
                                 selection.start = Point::new(
                                     start.row - 1,
-                                    map.buffer_snapshot.line_len(MultiBufferRow(start.row - 1)),
+                                    map.buffer_snapshot()
+                                        .line_len(MultiBufferRow(start.row - 1)),
                                 )
                                 .to_display_point(map)
                             }
@@ -706,9 +707,11 @@ impl Vim {
                         let end = selection.end.to_point(map);
                         if end.column == 0 && end > start {
                             let row = end.row.saturating_sub(1);
-                            selection.end =
-                                Point::new(row, map.buffer_snapshot.line_len(MultiBufferRow(row)))
-                                    .to_display_point(map);
+                            selection.end = Point::new(
+                                row,
+                                map.buffer_snapshot().line_len(MultiBufferRow(row)),
+                            )
+                            .to_display_point(map);
                         }
                     });
                 });
@@ -755,7 +758,7 @@ impl Vim {
                     .disjoint_anchors_arc()
                     .iter()
                     .map(|selection| {
-                        let start = selection.start.bias_left(&display_map.buffer_snapshot);
+                        let start = selection.start.bias_left(&display_map.buffer_snapshot());
                         start..start
                     })
                     .collect::<Vec<_>>();