Specify full TextStyles in EditorStyle

Nathan Sobo created

Change summary

gpui/src/fonts.rs            |  10 +++
server/src/rpc.rs            |   9 ++
zed/assets/themes/_base.toml |  10 +-
zed/src/editor.rs            | 126 +++++++++++++++++--------------------
zed/src/theme.rs             |  10 ++
5 files changed, 86 insertions(+), 79 deletions(-)

Detailed changes

gpui/src/fonts.rs šŸ”—

@@ -126,6 +126,16 @@ impl TextStyle {
     }
 }
 
+impl From<TextStyle> for HighlightStyle {
+    fn from(other: TextStyle) -> Self {
+        Self {
+            color: other.color,
+            font_properties: other.font_properties,
+            underline: other.underline,
+        }
+    }
+}
+
 impl HighlightStyle {
     fn from_json(json: HighlightStyleJson) -> Self {
         let font_properties = properties_from_json(json.weight, json.italic);

server/src/rpc.rs šŸ”—

@@ -1037,7 +1037,7 @@ mod tests {
     };
     use zed::{
         channel::{Channel, ChannelDetails, ChannelList},
-        editor::{Editor, Insert},
+        editor::{Editor, EditorStyle, Insert},
         fs::{FakeFs, Fs as _},
         language::LanguageRegistry,
         rpc::{self, Client, Credentials, EstablishConnectionError},
@@ -1122,7 +1122,12 @@ mod tests {
 
         // Create a selection set as client B and see that selection set as client A.
         let editor_b = cx_b.add_view(window_b, |cx| {
-            Editor::for_buffer(buffer_b, settings, |_| Default::default(), cx)
+            Editor::for_buffer(
+                buffer_b,
+                settings,
+                |cx| EditorStyle::test(cx.font_cache()),
+                cx,
+            )
         });
         buffer_a
             .condition(&cx_a, |buffer, _| buffer.selection_sets().count() == 1)

zed/assets/themes/_base.toml šŸ”—

@@ -107,8 +107,8 @@ shadow = { offset = [0, 2], blur = 16, color = "$shadow.0" }
 background = "$surface.1"
 corner_radius = 6
 padding = { left = 8, right = 8, top = 7, bottom = 7 }
-text = "$text.0.color"
-placeholder_text = "$text.2.color"
+text = "$text.0"
+placeholder_text = "$text.2"
 selection = "$selection.host"
 border = { width = 1, color = "$border.0" }
 
@@ -132,8 +132,8 @@ border = { width = 1, color = "$border.0" }
 background = "$surface.1"
 corner_radius = 6
 padding = { left = 16, right = 16, top = 7, bottom = 7 }
-text = "$text.0.color"
-placeholder_text = "$text.2.color"
+text = "$text.0"
+placeholder_text = "$text.2"
 selection = "$selection.host"
 border = { width = 1, color = "$border.0" }
 
@@ -153,7 +153,7 @@ background = "$state.hover"
 text = "$text.0"
 
 [editor]
-text = "$text.1.color"
+text = "$text.1"
 background = "$surface.1"
 gutter_background = "$surface.1"
 active_line_background = "$state.active_line"

zed/src/editor.rs šŸ”—

@@ -20,7 +20,7 @@ use gpui::{
     action,
     color::Color,
     font_cache::FamilyId,
-    fonts::{HighlightStyle, Properties as FontProperties},
+    fonts::{Properties as FontProperties, TextStyle},
     geometry::vector::Vector2F,
     keymap::Binding,
     text_layout::{self, RunStyle},
@@ -280,9 +280,9 @@ pub enum EditorMode {
 
 #[derive(Clone, Deserialize)]
 pub struct EditorStyle {
-    pub text: HighlightStyle,
+    pub text: TextStyle,
     #[serde(default)]
-    pub placeholder_text: Option<HighlightStyle>,
+    pub placeholder_text: Option<TextStyle>,
     pub background: Color,
     pub selection: SelectionStyle,
     pub gutter_background: Color,
@@ -2520,7 +2520,7 @@ impl Snapshot {
                         .theme
                         .syntax
                         .highlight_style(style_ix)
-                        .unwrap_or(style.text.clone());
+                        .unwrap_or(style.text.clone().into());
                     // Avoid a lookup if the font properties match the previous ones.
                     let font_id = if style.font_properties == prev_font_properties {
                         prev_font_id
@@ -2597,17 +2597,19 @@ impl Snapshot {
 }
 
 impl EditorStyle {
-    fn placeholder_text(&self) -> &HighlightStyle {
-        self.placeholder_text.as_ref().unwrap_or(&self.text)
-    }
-}
-
-impl Default for EditorStyle {
-    fn default() -> Self {
+    #[cfg(any(test, feature ="test-support"))]
+    pub fn test(font_cache: &FontCache) -> Self {
+        let font_family_name = "Monaco";
+        let font_properties = Default::default();
+        let family_id = font_cache.load_family(&[font_family_name]).unwrap();
+        let font_id = font_cache.select_font(family_id, &font_properties).unwrap();
         Self {
-            text: HighlightStyle {
+            text: TextStyle {
+                font_family_name: font_family_name.into(),
+                font_id,
+                font_size: 14.,
                 color: Color::from_u32(0xff0000ff),
-                font_properties: Default::default(),
+                font_properties,
                 underline: false,
             },
             placeholder_text: None,
@@ -2620,6 +2622,10 @@ impl Default for EditorStyle {
             guest_selections: Default::default(),
         }
     }
+
+    fn placeholder_text(&self) -> &TextStyle {
+        self.placeholder_text.as_ref().unwrap_or(&self.text)
+    }
 }
 
 fn compute_scroll_position(
@@ -2800,9 +2806,8 @@ mod tests {
     fn test_selection_with_mouse(cx: &mut gpui::MutableAppContext) {
         let buffer = cx.add_model(|cx| Buffer::new(0, "aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx));
         let settings = settings::test(&cx).1;
-        let (_, editor) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer, settings, |_| Default::default(), cx)
-        });
+        let (_, editor) =
+            cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
 
         editor.update(cx, |view, cx| {
             view.begin_selection(DisplayPoint::new(2, 2), false, cx);
@@ -2868,9 +2873,7 @@ mod tests {
     fn test_canceling_pending_selection(cx: &mut gpui::MutableAppContext) {
         let buffer = cx.add_model(|cx| Buffer::new(0, "aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx));
         let settings = settings::test(&cx).1;
-        let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer, settings, |_| Default::default(), cx)
-        });
+        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
 
         view.update(cx, |view, cx| {
             view.begin_selection(DisplayPoint::new(2, 2), false, cx);
@@ -2902,9 +2905,7 @@ mod tests {
     fn test_cancel(cx: &mut gpui::MutableAppContext) {
         let buffer = cx.add_model(|cx| Buffer::new(0, "aaaaaa\nbbbbbb\ncccccc\ndddddd\n", cx));
         let settings = settings::test(&cx).1;
-        let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer, settings, |_| Default::default(), cx)
-        });
+        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
 
         view.update(cx, |view, cx| {
             view.begin_selection(DisplayPoint::new(3, 4), false, cx);
@@ -2949,7 +2950,7 @@ mod tests {
 
         let settings = settings::test(&cx).1;
         let (_, editor) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer.clone(), settings.clone(), |_| Default::default(), cx)
+            build_editor(buffer, settings.clone(), cx)
         });
 
         let layouts = editor.update(cx, |editor, cx| {
@@ -2995,7 +2996,7 @@ mod tests {
         });
         let settings = settings::test(&cx).1;
         let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer.clone(), settings, |_| Default::default(), cx)
+            build_editor(buffer.clone(), settings, cx)
         });
 
         view.update(cx, |view, cx| {
@@ -3063,7 +3064,7 @@ mod tests {
         let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(6, 6), cx));
         let settings = settings::test(&cx).1;
         let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer.clone(), settings, |_| Default::default(), cx)
+            build_editor(buffer.clone(), settings, cx)
         });
 
         buffer.update(cx, |buffer, cx| {
@@ -3140,7 +3141,7 @@ mod tests {
         let buffer = cx.add_model(|cx| Buffer::new(0, "ⓐⓑⓒⓓⓔ\nabcde\nαβγΓε\n", cx));
         let settings = settings::test(&cx).1;
         let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer.clone(), settings, |_| Default::default(), cx)
+            build_editor(buffer.clone(), settings, cx)
         });
 
         assert_eq!('ⓐ'.len_utf8(), 3);
@@ -3198,7 +3199,7 @@ mod tests {
         let buffer = cx.add_model(|cx| Buffer::new(0, "ⓐⓑⓒⓓⓔ\nabcd\nαβγ\nabcd\nⓐⓑⓒⓓⓔ\n", cx));
         let settings = settings::test(&cx).1;
         let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer.clone(), settings, |_| Default::default(), cx)
+            build_editor(buffer.clone(), settings, cx)
         });
         view.update(cx, |view, cx| {
             view.select_display_ranges(&[empty_range(0, "ⓐⓑⓒⓓⓔ".len())], cx)
@@ -3228,9 +3229,7 @@ mod tests {
     fn test_beginning_end_of_line(cx: &mut gpui::MutableAppContext) {
         let buffer = cx.add_model(|cx| Buffer::new(0, "abc\n  def", cx));
         let settings = settings::test(&cx).1;
-        let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer, settings, |_| Default::default(), cx)
-        });
+        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
         view.update(cx, |view, cx| {
             view.select_display_ranges(
                 &[
@@ -3373,9 +3372,7 @@ mod tests {
         let buffer =
             cx.add_model(|cx| Buffer::new(0, "use std::str::{foo, bar}\n\n  {baz.qux()}", cx));
         let settings = settings::test(&cx).1;
-        let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer, settings, |_| Default::default(), cx)
-        });
+        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
         view.update(cx, |view, cx| {
             view.select_display_ranges(
                 &[
@@ -3567,9 +3564,7 @@ mod tests {
         let buffer =
             cx.add_model(|cx| Buffer::new(0, "use one::{\n    two::three::four::five\n};", cx));
         let settings = settings::test(&cx).1;
-        let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer, settings, |_| Default::default(), cx)
-        });
+        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
 
         view.update(cx, |view, cx| {
             view.set_wrap_width(130., cx);
@@ -3630,7 +3625,7 @@ mod tests {
         });
         let settings = settings::test(&cx).1;
         let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer.clone(), settings, |_| Default::default(), cx)
+            build_editor(buffer.clone(), settings, cx)
         });
 
         view.update(cx, |view, cx| {
@@ -3666,7 +3661,7 @@ mod tests {
         });
         let settings = settings::test(&cx).1;
         let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer.clone(), settings, |_| Default::default(), cx)
+            build_editor(buffer.clone(), settings, cx)
         });
 
         view.update(cx, |view, cx| {
@@ -3695,9 +3690,7 @@ mod tests {
     fn test_delete_line(cx: &mut gpui::MutableAppContext) {
         let settings = settings::test(&cx).1;
         let buffer = cx.add_model(|cx| Buffer::new(0, "abc\ndef\nghi\n", cx));
-        let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer, settings, |_| Default::default(), cx)
-        });
+        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
         view.update(cx, |view, cx| {
             view.select_display_ranges(
                 &[
@@ -3721,9 +3714,7 @@ mod tests {
 
         let settings = settings::test(&cx).1;
         let buffer = cx.add_model(|cx| Buffer::new(0, "abc\ndef\nghi\n", cx));
-        let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer, settings, |_| Default::default(), cx)
-        });
+        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
         view.update(cx, |view, cx| {
             view.select_display_ranges(&[DisplayPoint::new(2, 0)..DisplayPoint::new(0, 1)], cx)
                 .unwrap();
@@ -3740,9 +3731,7 @@ mod tests {
     fn test_duplicate_line(cx: &mut gpui::MutableAppContext) {
         let settings = settings::test(&cx).1;
         let buffer = cx.add_model(|cx| Buffer::new(0, "abc\ndef\nghi\n", cx));
-        let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer, settings, |_| Default::default(), cx)
-        });
+        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
         view.update(cx, |view, cx| {
             view.select_display_ranges(
                 &[
@@ -3769,9 +3758,7 @@ mod tests {
 
         let settings = settings::test(&cx).1;
         let buffer = cx.add_model(|cx| Buffer::new(0, "abc\ndef\nghi\n", cx));
-        let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer, settings, |_| Default::default(), cx)
-        });
+        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
         view.update(cx, |view, cx| {
             view.select_display_ranges(
                 &[
@@ -3797,9 +3784,7 @@ mod tests {
     fn test_move_line_up_down(cx: &mut gpui::MutableAppContext) {
         let settings = settings::test(&cx).1;
         let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(10, 5), cx));
-        let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer, settings, |_| Default::default(), cx)
-        });
+        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
         view.update(cx, |view, cx| {
             view.fold_ranges(
                 vec![
@@ -3898,7 +3883,7 @@ mod tests {
         let settings = settings::test(&cx).1;
         let view = cx
             .add_window(Default::default(), |cx| {
-                Editor::for_buffer(buffer.clone(), settings, |_| Default::default(), cx)
+                build_editor(buffer.clone(), settings, cx)
             })
             .1;
 
@@ -4031,9 +4016,7 @@ mod tests {
     fn test_select_all(cx: &mut gpui::MutableAppContext) {
         let buffer = cx.add_model(|cx| Buffer::new(0, "abc\nde\nfgh", cx));
         let settings = settings::test(&cx).1;
-        let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer, settings, |_| Default::default(), cx)
-        });
+        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
         view.update(cx, |view, cx| {
             view.select_all(&SelectAll, cx);
             assert_eq!(
@@ -4047,9 +4030,7 @@ mod tests {
     fn test_select_line(cx: &mut gpui::MutableAppContext) {
         let settings = settings::test(&cx).1;
         let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(6, 5), cx));
-        let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer, settings, |_| Default::default(), cx)
-        });
+        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
         view.update(cx, |view, cx| {
             view.select_display_ranges(
                 &[
@@ -4095,9 +4076,7 @@ mod tests {
     fn test_split_selection_into_lines(cx: &mut gpui::MutableAppContext) {
         let settings = settings::test(&cx).1;
         let buffer = cx.add_model(|cx| Buffer::new(0, sample_text(9, 5), cx));
-        let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer, settings, |_| Default::default(), cx)
-        });
+        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
         view.update(cx, |view, cx| {
             view.fold_ranges(
                 vec![
@@ -4165,9 +4144,7 @@ mod tests {
     fn test_add_selection_above_below(cx: &mut gpui::MutableAppContext) {
         let settings = settings::test(&cx).1;
         let buffer = cx.add_model(|cx| Buffer::new(0, "abc\ndefghi\n\njk\nlmno\n", cx));
-        let (_, view) = cx.add_window(Default::default(), |cx| {
-            Editor::for_buffer(buffer, settings, |_| Default::default(), cx)
-        });
+        let (_, view) = cx.add_window(Default::default(), |cx| build_editor(buffer, settings, cx));
 
         view.update(cx, |view, cx| {
             view.select_display_ranges(&[DisplayPoint::new(1, 3)..DisplayPoint::new(1, 3)], cx)
@@ -4353,9 +4330,7 @@ mod tests {
             let history = History::new(text.into());
             Buffer::from_history(0, history, None, lang.cloned(), cx)
         });
-        let (_, view) = cx.add_window(|cx| {
-            Editor::for_buffer(buffer, settings.clone(), |_| Default::default(), cx)
-        });
+        let (_, view) = cx.add_window(|cx| build_editor(buffer, settings.clone(), cx));
         view.condition(&cx, |view, cx| !view.buffer.read(cx).is_parsing())
             .await;
 
@@ -4493,6 +4468,19 @@ mod tests {
         let point = DisplayPoint::new(row as u32, column as u32);
         point..point
     }
+
+    fn build_editor(
+        buffer: ModelHandle<Buffer>,
+        settings: watch::Receiver<Settings>,
+        cx: &mut ViewContext<Editor>,
+    ) -> Editor {
+        Editor::for_buffer(
+            buffer,
+            settings,
+            move |cx| EditorStyle::test(cx.font_cache()),
+            cx,
+        )
+    }
 }
 
 trait RangeExt<T> {

zed/src/theme.rs šŸ”—

@@ -163,9 +163,9 @@ pub struct ContainedLabel {
 pub struct InputEditorStyle {
     #[serde(flatten)]
     pub container: ContainerStyle,
-    pub text: HighlightStyle,
+    pub text: TextStyle,
     #[serde(default)]
-    pub placeholder_text: Option<HighlightStyle>,
+    pub placeholder_text: Option<TextStyle>,
     pub selection: SelectionStyle,
 }
 
@@ -196,7 +196,11 @@ impl InputEditorStyle {
                 .background_color
                 .unwrap_or(Color::transparent_black()),
             selection: self.selection,
-            ..Default::default()
+            gutter_background: Default::default(),
+            active_line_background: Default::default(),
+            line_number: Default::default(),
+            line_number_active: Default::default(),
+            guest_selections: Default::default(),
         }
     }
 }