Do not add extra spaces to hints

Kirill Bulatov created

Change summary

crates/editor/src/display_map/inlay_map.rs | 89 ++++++++++++++++++++++++
crates/editor/src/editor.rs                | 11 --
2 files changed, 90 insertions(+), 10 deletions(-)

Detailed changes

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

@@ -49,6 +49,19 @@ pub struct InlayProperties<T> {
     pub text: T,
 }
 
+impl InlayProperties<String> {
+    pub fn new(position: Anchor, hint: &project::InlayHint) -> Self {
+        let mut text = hint.text();
+        if hint.padding_right && !text.ends_with(' ') {
+            text.push(' ');
+        }
+        if hint.padding_left && !text.starts_with(' ') {
+            text.insert(0, ' ');
+        }
+        Self { position, text }
+    }
+}
+
 impl sum_tree::Item for Transform {
     type Summary = TransformSummary;
 
@@ -1095,6 +1108,7 @@ mod tests {
     use super::*;
     use crate::{InlayId, MultiBuffer};
     use gpui::AppContext;
+    use project::{InlayHint, InlayHintLabel};
     use rand::prelude::*;
     use settings::SettingsStore;
     use std::{cmp::Reverse, env, sync::Arc};
@@ -1102,6 +1116,81 @@ mod tests {
     use text::Patch;
     use util::post_inc;
 
+    #[test]
+    fn test_inlay_properties_label_padding() {
+        assert_eq!(
+            InlayProperties::new(
+                Anchor::min(),
+                &InlayHint {
+                    label: InlayHintLabel::String("a".to_string()),
+                    buffer_id: 0,
+                    position: text::Anchor::default(),
+                    padding_left: false,
+                    padding_right: false,
+                    tooltip: None,
+                    kind: None,
+                },
+            )
+            .text,
+            "a",
+            "Should not pad label if not requested"
+        );
+
+        assert_eq!(
+            InlayProperties::new(
+                Anchor::min(),
+                &InlayHint {
+                    label: InlayHintLabel::String("a".to_string()),
+                    buffer_id: 0,
+                    position: text::Anchor::default(),
+                    padding_left: true,
+                    padding_right: true,
+                    tooltip: None,
+                    kind: None,
+                },
+            )
+            .text,
+            " a ",
+            "Should pad label for every side requested"
+        );
+
+        assert_eq!(
+            InlayProperties::new(
+                Anchor::min(),
+                &InlayHint {
+                    label: InlayHintLabel::String(" a ".to_string()),
+                    buffer_id: 0,
+                    position: text::Anchor::default(),
+                    padding_left: false,
+                    padding_right: false,
+                    tooltip: None,
+                    kind: None,
+                },
+            )
+            .text,
+            " a ",
+            "Should not change already padded label"
+        );
+
+        assert_eq!(
+            InlayProperties::new(
+                Anchor::min(),
+                &InlayHint {
+                    label: InlayHintLabel::String(" a ".to_string()),
+                    buffer_id: 0,
+                    position: text::Anchor::default(),
+                    padding_left: true,
+                    padding_right: true,
+                    tooltip: None,
+                    kind: None,
+                },
+            )
+            .text,
+            " a ",
+            "Should not change already padded label"
+        );
+    }
+
     #[gpui::test]
     fn test_basic_inlays(cx: &mut AppContext) {
         let buffer = MultiBuffer::build_simple("abcdefghi", cx);

crates/editor/src/editor.rs 🔗

@@ -2712,16 +2712,7 @@ impl Editor {
         let buffer = self.buffer.read(cx).read(cx);
         let new_inlays = to_insert
             .into_iter()
-            .map(|(position, id, hint)| {
-                let mut text = hint.text();
-                if hint.padding_right {
-                    text.push(' ');
-                }
-                if hint.padding_left {
-                    text.insert(0, ' ');
-                }
-                (id, InlayProperties { position, text })
-            })
+            .map(|(position, id, hint)| (id, InlayProperties::new(position, &hint)))
             .collect();
         drop(buffer);
         self.display_map.update(cx, |display_map, cx| {