Correctly incorporate editor settings into diagnostic header rendering

Max Brunsfeld created

Change summary

crates/chat_panel/src/chat_panel.rs         |  4 +-
crates/diagnostics/src/diagnostics.rs       | 30 +++--------------
crates/editor/src/editor.rs                 | 39 ++++++++++++----------
crates/editor/src/element.rs                |  4 +-
crates/file_finder/src/file_finder.rs       |  3 -
crates/go_to_line/src/go_to_line.rs         |  5 +-
crates/server/src/rpc.rs                    |  3 -
crates/theme_selector/src/theme_selector.rs |  4 +-
8 files changed, 37 insertions(+), 55 deletions(-)

Detailed changes

crates/chat_panel/src/chat_panel.rs 🔗

@@ -13,7 +13,7 @@ use gpui::{
     ViewContext, ViewHandle,
 };
 use postage::{prelude::Stream, watch};
-use std::{rc::Rc, sync::Arc};
+use std::sync::Arc;
 use time::{OffsetDateTime, UtcOffset};
 use util::{ResultExt, TryFutureExt};
 use workspace::Settings;
@@ -56,7 +56,7 @@ impl ChatPanel {
                 4,
                 {
                     let settings = settings.clone();
-                    Rc::new(move |_| {
+                    Arc::new(move |_| {
                         let settings = settings.borrow();
                         EditorSettings {
                             tab_size: settings.tab_size,

crates/diagnostics/src/diagnostics.rs 🔗

@@ -1,7 +1,5 @@
-use std::{cmp, sync::Arc};
-
 use editor::{
-    diagnostic_block_renderer, diagnostic_style,
+    diagnostic_block_renderer, diagnostic_header_renderer,
     display_map::{BlockDisposition, BlockProperties},
     Editor, ExcerptProperties, MultiBuffer,
 };
@@ -12,6 +10,7 @@ use gpui::{
 use language::Point;
 use postage::watch;
 use project::Project;
+use std::cmp;
 use workspace::Workspace;
 
 action!(Toggle);
@@ -129,27 +128,10 @@ impl workspace::Item for ProjectDiagnostics {
                                                 .count()
                                                 as u8
                                                 + 1,
-                                            render_header: Some(Arc::new({
-                                                let settings = settings.clone();
-
-                                                move |_| {
-                                                    let editor_style =
-                                                        &settings.borrow().theme.editor;
-                                                    let mut text_style = editor_style.text.clone();
-                                                    text_style.color = diagnostic_style(
-                                                        primary_diagnostic.severity,
-                                                        true,
-                                                        &editor_style,
-                                                    )
-                                                    .text;
-
-                                                    Text::new(
-                                                        primary_diagnostic.message.clone(),
-                                                        text_style,
-                                                    )
-                                                    .boxed()
-                                                }
-                                            })),
+                                            render_header: Some(diagnostic_header_renderer(
+                                                primary_diagnostic,
+                                                build_settings.clone(),
+                                            )),
                                         },
                                         excerpts_cx,
                                     );

crates/editor/src/editor.rs 🔗

@@ -28,7 +28,9 @@ use language::{
     TransactionId,
 };
 pub use multi_buffer::{Anchor, ExcerptProperties, MultiBuffer};
-use multi_buffer::{AnchorRangeExt, MultiBufferChunks, MultiBufferSnapshot, ToOffset, ToPoint};
+use multi_buffer::{
+    AnchorRangeExt, MultiBufferChunks, MultiBufferSnapshot, RenderHeaderFn, ToOffset, ToPoint,
+};
 use postage::watch;
 use serde::{Deserialize, Serialize};
 use smallvec::SmallVec;
@@ -39,7 +41,6 @@ use std::{
     iter::{self, FromIterator},
     mem,
     ops::{Deref, Range, RangeInclusive, Sub},
-    rc::Rc,
     sync::Arc,
     time::{Duration, Instant},
 };
@@ -356,7 +357,7 @@ pub enum SoftWrap {
     Column(u32),
 }
 
-type BuildSettings = Rc<dyn Fn(&AppContext) -> EditorSettings>;
+type BuildSettings = Arc<dyn 'static + Send + Sync + Fn(&AppContext) -> EditorSettings>;
 
 pub struct Editor {
     handle: WeakViewHandle<Self>,
@@ -3771,24 +3772,26 @@ pub fn diagnostic_block_renderer(
     build_settings: BuildSettings,
 ) -> RenderBlock {
     Arc::new(move |cx: &BlockContext| {
-        let diagnostic = diagnostic.clone();
         let settings = build_settings(cx);
-        render_diagnostic(diagnostic, &settings.style, is_valid, cx.anchor_x)
+        let mut text_style = settings.style.text.clone();
+        text_style.color = diagnostic_style(diagnostic.severity, is_valid, &settings.style).text;
+        Text::new(diagnostic.message.clone(), text_style)
+            .contained()
+            .with_margin_left(cx.anchor_x)
+            .boxed()
     })
 }
 
-fn render_diagnostic(
+pub fn diagnostic_header_renderer(
     diagnostic: Diagnostic,
-    style: &EditorStyle,
-    valid: bool,
-    anchor_x: f32,
-) -> ElementBox {
-    let mut text_style = style.text.clone();
-    text_style.color = diagnostic_style(diagnostic.severity, valid, &style).text;
-    Text::new(diagnostic.message, text_style)
-        .contained()
-        .with_margin_left(anchor_x)
-        .boxed()
+    build_settings: BuildSettings,
+) -> RenderHeaderFn {
+    Arc::new(move |cx| {
+        let settings = build_settings(cx);
+        let mut text_style = settings.style.text.clone();
+        text_style.color = diagnostic_style(diagnostic.severity, true, &settings.style).text;
+        Text::new(diagnostic.message.clone(), text_style).boxed()
+    })
 }
 
 pub fn diagnostic_style(
@@ -3813,7 +3816,7 @@ pub fn settings_builder(
     buffer: WeakModelHandle<MultiBuffer>,
     settings: watch::Receiver<workspace::Settings>,
 ) -> BuildSettings {
-    Rc::new(move |cx| {
+    Arc::new(move |cx| {
         let settings = settings.borrow();
         let font_cache = cx.font_cache();
         let font_family_id = settings.buffer_font_family;
@@ -6106,7 +6109,7 @@ mod tests {
         settings: EditorSettings,
         cx: &mut ViewContext<Editor>,
     ) -> Editor {
-        Editor::for_buffer(buffer, Rc::new(move |_| settings.clone()), cx)
+        Editor::for_buffer(buffer, Arc::new(move |_| settings.clone()), cx)
     }
 }
 

crates/editor/src/element.rs 🔗

@@ -1179,7 +1179,7 @@ fn scale_horizontal_mouse_autoscroll_delta(delta: f32) -> f32 {
 mod tests {
     use super::*;
     use crate::{Editor, EditorSettings, MultiBuffer};
-    use std::rc::Rc;
+    use std::sync::Arc;
     use util::test::sample_text;
 
     #[gpui::test]
@@ -1191,7 +1191,7 @@ mod tests {
                 buffer,
                 {
                     let settings = settings.clone();
-                    Rc::new(move |_| settings.clone())
+                    Arc::new(move |_| settings.clone())
                 },
                 cx,
             )

crates/file_finder/src/file_finder.rs 🔗

@@ -16,7 +16,6 @@ use project::{Project, ProjectPath};
 use std::{
     cmp,
     path::Path,
-    rc::Rc,
     sync::{
         atomic::{self, AtomicBool},
         Arc,
@@ -271,7 +270,7 @@ impl FileFinder {
             Editor::single_line(
                 {
                     let settings = settings.clone();
-                    Rc::new(move |_| {
+                    Arc::new(move |_| {
                         let settings = settings.borrow();
                         EditorSettings {
                             style: settings.theme.selector.input_editor.as_editor(),

crates/go_to_line/src/go_to_line.rs 🔗

@@ -1,11 +1,10 @@
-use std::rc::Rc;
-
 use editor::{display_map::ToDisplayPoint, Autoscroll, Editor, EditorSettings};
 use gpui::{
     action, elements::*, geometry::vector::Vector2F, keymap::Binding, Axis, Entity,
     MutableAppContext, RenderContext, View, ViewContext, ViewHandle,
 };
 use postage::watch;
+use std::sync::Arc;
 use text::{Bias, Point, Selection};
 use workspace::{Settings, Workspace};
 
@@ -51,7 +50,7 @@ impl GoToLine {
             Editor::single_line(
                 {
                     let settings = settings.clone();
-                    Rc::new(move |_| {
+                    Arc::new(move |_| {
                         let settings = settings.borrow();
                         EditorSettings {
                             tab_size: settings.tab_size,

crates/server/src/rpc.rs 🔗

@@ -932,7 +932,6 @@ mod tests {
     use std::{
         ops::Deref,
         path::Path,
-        rc::Rc,
         sync::{
             atomic::{AtomicBool, Ordering::SeqCst},
             Arc,
@@ -1047,7 +1046,7 @@ mod tests {
             .unwrap();
 
         let editor_b = cx_b.add_view(window_b, |cx| {
-            Editor::for_buffer(buffer_b, Rc::new(|cx| EditorSettings::test(cx)), cx)
+            Editor::for_buffer(buffer_b, Arc::new(|cx| EditorSettings::test(cx)), cx)
         });
         // TODO
         // // Create a selection set as client B and see that selection set as client A.

crates/theme_selector/src/theme_selector.rs 🔗

@@ -9,7 +9,7 @@ use gpui::{
 };
 use parking_lot::Mutex;
 use postage::watch;
-use std::{cmp, rc::Rc, sync::Arc};
+use std::{cmp, sync::Arc};
 use theme::ThemeRegistry;
 use workspace::{Settings, Workspace};
 
@@ -64,7 +64,7 @@ impl ThemeSelector {
             Editor::single_line(
                 {
                     let settings = settings.clone();
-                    Rc::new(move |_| {
+                    Arc::new(move |_| {
                         let settings = settings.borrow();
                         EditorSettings {
                             tab_size: settings.tab_size,