Fix bracket colorization not working in file-less files with a proper language (#43947)

Kirill Bulatov created

Follow-up of https://github.com/zed-industries/zed/pull/43172

Release Notes:

- Fixed bracket colorization in file-less files with a proper language

Change summary

crates/editor/src/bracket_colorization.rs | 38 +++++++++++++++++++++++-
crates/editor/src/editor.rs               | 20 +++++++++---
crates/editor/src/inlays/inlay_hints.rs   |  4 +-
crates/editor/src/lsp_colors.rs           |  2 
4 files changed, 54 insertions(+), 10 deletions(-)

Detailed changes

crates/editor/src/bracket_colorization.rs πŸ”—

@@ -43,7 +43,7 @@ impl Editor {
                 .collect_array()
         };
 
-        let bracket_matches_by_accent = self.visible_excerpts(cx).into_iter().fold(
+        let bracket_matches_by_accent = self.visible_excerpts(false, cx).into_iter().fold(
             HashMap::default(),
             |mut acc, (excerpt_id, (buffer, buffer_version, buffer_range))| {
                 let buffer_snapshot = buffer.read(cx).snapshot();
@@ -164,7 +164,7 @@ mod tests {
 
     use super::*;
     use crate::{
-        DisplayPoint, EditorSnapshot, MoveToBeginning, MoveToEnd, MoveUp,
+        DisplayPoint, EditorMode, EditorSnapshot, MoveToBeginning, MoveToEnd, MoveUp,
         display_map::{DisplayRow, ToDisplayPoint},
         editor_tests::init_test,
         test::{
@@ -276,6 +276,40 @@ where
         );
     }
 
+    #[gpui::test]
+    async fn test_file_less_file_colorization(cx: &mut gpui::TestAppContext) {
+        init_test(cx, |language_settings| {
+            language_settings.defaults.colorize_brackets = Some(true);
+        });
+        let editor = cx.add_window(|window, cx| {
+            let multi_buffer = MultiBuffer::build_simple("fn main() {}", cx);
+            multi_buffer.update(cx, |multi_buffer, cx| {
+                multi_buffer
+                    .as_singleton()
+                    .unwrap()
+                    .update(cx, |buffer, cx| {
+                        buffer.set_language(Some(rust_lang()), cx);
+                    });
+            });
+            Editor::new(EditorMode::full(), multi_buffer, None, window, cx)
+        });
+
+        cx.executor().advance_clock(Duration::from_millis(100));
+        cx.executor().run_until_parked();
+
+        assert_eq!(
+            "fn mainΒ«1()1Β» Β«1{}1Β»
+1 hsla(207.80, 16.20%, 69.19%, 1.00)
+",
+            editor
+                .update(cx, |editor, window, cx| {
+                    editor_bracket_colors_markup(&editor.snapshot(window, cx))
+                })
+                .unwrap(),
+            "File-less buffer should still have its brackets colorized"
+        );
+    }
+
     #[gpui::test]
     async fn test_markdown_bracket_colorization(cx: &mut gpui::TestAppContext) {
         init_test(cx, |language_settings| {

crates/editor/src/editor.rs πŸ”—

@@ -5308,12 +5308,10 @@ impl Editor {
 
     pub fn visible_excerpts(
         &self,
+        lsp_related_only: bool,
         cx: &mut Context<Editor>,
     ) -> HashMap<ExcerptId, (Entity<Buffer>, clock::Global, Range<usize>)> {
-        let Some(project) = self.project() else {
-            return HashMap::default();
-        };
-        let project = project.read(cx);
+        let project = self.project().cloned();
         let multi_buffer = self.buffer().read(cx);
         let multi_buffer_snapshot = multi_buffer.snapshot(cx);
         let multi_buffer_visible_start = self
@@ -5331,6 +5329,18 @@ impl Editor {
             .into_iter()
             .filter(|(_, excerpt_visible_range, _)| !excerpt_visible_range.is_empty())
             .filter_map(|(buffer, excerpt_visible_range, excerpt_id)| {
+                if !lsp_related_only {
+                    return Some((
+                        excerpt_id,
+                        (
+                            multi_buffer.buffer(buffer.remote_id()).unwrap(),
+                            buffer.version().clone(),
+                            excerpt_visible_range.start.0..excerpt_visible_range.end.0,
+                        ),
+                    ));
+                }
+
+                let project = project.as_ref()?.read(cx);
                 let buffer_file = project::File::from_dyn(buffer.file())?;
                 let buffer_worktree = project.worktree_for_id(buffer_file.worktree_id(cx), cx)?;
                 let worktree_entry = buffer_worktree
@@ -22592,7 +22602,7 @@ impl Editor {
         if self.ignore_lsp_data() {
             return;
         }
-        for (_, (visible_buffer, _, _)) in self.visible_excerpts(cx) {
+        for (_, (visible_buffer, _, _)) in self.visible_excerpts(true, cx) {
             self.register_buffer(visible_buffer.read(cx).remote_id(), cx);
         }
     }

crates/editor/src/inlays/inlay_hints.rs πŸ”—

@@ -291,7 +291,7 @@ impl Editor {
             }),
         };
 
-        let mut visible_excerpts = self.visible_excerpts(cx);
+        let mut visible_excerpts = self.visible_excerpts(true, cx);
         let mut invalidate_hints_for_buffers = HashSet::default();
         let ignore_previous_fetches = match reason {
             InlayHintRefreshReason::ModifiersChanged(_)
@@ -2211,7 +2211,7 @@ pub mod tests {
         cx: &mut gpui::TestAppContext,
     ) -> Range<Point> {
         let ranges = editor
-            .update(cx, |editor, _window, cx| editor.visible_excerpts(cx))
+            .update(cx, |editor, _window, cx| editor.visible_excerpts(true, cx))
             .unwrap();
         assert_eq!(
             ranges.len(),

crates/editor/src/lsp_colors.rs πŸ”—

@@ -164,7 +164,7 @@ impl Editor {
         }
 
         let visible_buffers = self
-            .visible_excerpts(cx)
+            .visible_excerpts(true, cx)
             .into_values()
             .map(|(buffer, ..)| buffer)
             .filter(|editor_buffer| {