Add ability to display backgrounds for inlay hints (#18010)

Marshall Bowers created

This PR adds the ability to display backgrounds for inlay hints within
the editor.

This is controlled by the new `inlay_hints.show_background` setting.
This setting defaults to `false`.

To enable the setting, add the following to your `settings.json`:

```json
{
  "inlay_hints": {
    "enabled": true,
    "show_background": true
  }
}
```

When enabled, the inlay hint backgrounds will use the `hint.background`
color from the theme.

| Disabled | Enabled |
|
--------------------------------------------------------------------------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------------------------------------------------------------------------
|
| <img width="1624" alt="Screenshot 2024-09-17 at 4 21 53 PM"
src="https://github.com/user-attachments/assets/5534d09b-1e22-4c6f-9d82-314796ed7d22">
| <img width="1624" alt="Screenshot 2024-09-17 at 4 21 43 PM"
src="https://github.com/user-attachments/assets/6ec58cde-6115-4db4-be95-97c5f2f54b2d">
|

Related issues:

- #12485
- #17392

Release Notes:

- Added an `inlay_hints.show_background` setting to allow displaying
backgrounds for inlay hints in the editor.
  - This setting defaults to `false`.
- If enabled, the inlay hint backgrounds will use the `hint.background`
color from the theme.

Change summary

assets/settings/default.json             |  4 ++++
crates/assistant/src/prompt_library.rs   |  6 ++----
crates/collab/src/tests/editor_tests.rs  |  4 ++++
crates/editor/src/editor.rs              | 21 +++++++++++++++------
crates/editor/src/hover_links.rs         |  1 +
crates/editor/src/hover_popover.rs       |  1 +
crates/editor/src/inlay_hint_cache.rs    | 15 +++++++++++++++
crates/language/src/language_settings.rs |  8 ++++++++
docs/src/configuring-zed.md              |  1 +
9 files changed, 51 insertions(+), 10 deletions(-)

Detailed changes

assets/settings/default.json 🔗

@@ -318,6 +318,10 @@
     "show_parameter_hints": true,
     // Corresponds to null/None LSP hint type value.
     "show_other_hints": true,
+    // Whether to show a background for inlay hints.
+    //
+    // If set to `true`, the background will use the `hint.background` color from the current theme.
+    "show_background": false,
     // Time to wait after editing the buffer, before requesting the hints,
     // set to 0 to disable debouncing.
     "edit_debounce_ms": 700,

crates/assistant/src/prompt_library.rs 🔗

@@ -921,10 +921,8 @@ impl PromptLibrary {
                                                     scrollbar_width: Pixels::ZERO,
                                                     syntax: cx.theme().syntax().clone(),
                                                     status: cx.theme().status().clone(),
-                                                    inlay_hints_style: HighlightStyle {
-                                                        color: Some(cx.theme().status().hint),
-                                                        ..HighlightStyle::default()
-                                                    },
+                                                    inlay_hints_style:
+                                                        editor::make_inlay_hints_style(cx),
                                                     suggestions_style: HighlightStyle {
                                                         color: Some(cx.theme().status().predictive),
                                                         ..HighlightStyle::default()

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

@@ -1524,6 +1524,7 @@ async fn test_mutual_editor_inlay_hint_cache_update(
                     show_type_hints: true,
                     show_parameter_hints: false,
                     show_other_hints: true,
+                    show_background: false,
                 })
             });
         });
@@ -1538,6 +1539,7 @@ async fn test_mutual_editor_inlay_hint_cache_update(
                     show_type_hints: true,
                     show_parameter_hints: false,
                     show_other_hints: true,
+                    show_background: false,
                 })
             });
         });
@@ -1786,6 +1788,7 @@ async fn test_inlay_hint_refresh_is_forwarded(
                     show_type_hints: false,
                     show_parameter_hints: false,
                     show_other_hints: false,
+                    show_background: false,
                 })
             });
         });
@@ -1800,6 +1803,7 @@ async fn test_inlay_hint_refresh_is_forwarded(
                     show_type_hints: true,
                     show_parameter_hints: true,
                     show_other_hints: true,
+                    show_background: false,
                 })
             });
         });

crates/editor/src/editor.rs 🔗

@@ -412,6 +412,19 @@ impl Default for EditorStyle {
     }
 }
 
+pub fn make_inlay_hints_style(cx: &WindowContext) -> HighlightStyle {
+    let show_background = all_language_settings(None, cx)
+        .language(None)
+        .inlay_hints
+        .show_background;
+
+    HighlightStyle {
+        color: Some(cx.theme().status().hint),
+        background_color: show_background.then(|| cx.theme().status().hint_background),
+        ..HighlightStyle::default()
+    }
+}
+
 type CompletionId = usize;
 
 #[derive(Clone, Debug)]
@@ -10034,9 +10047,8 @@ impl Editor {
                                                 syntax: cx.editor_style.syntax.clone(),
                                                 status: cx.editor_style.status.clone(),
                                                 inlay_hints_style: HighlightStyle {
-                                                    color: Some(cx.theme().status().hint),
                                                     font_weight: Some(FontWeight::BOLD),
-                                                    ..HighlightStyle::default()
+                                                    ..make_inlay_hints_style(cx)
                                                 },
                                                 suggestions_style: HighlightStyle {
                                                     color: Some(cx.theme().status().predictive),
@@ -12992,10 +13004,7 @@ impl Render for Editor {
                 scrollbar_width: EditorElement::SCROLLBAR_WIDTH,
                 syntax: cx.theme().syntax().clone(),
                 status: cx.theme().status().clone(),
-                inlay_hints_style: HighlightStyle {
-                    color: Some(cx.theme().status().hint),
-                    ..HighlightStyle::default()
-                },
+                inlay_hints_style: make_inlay_hints_style(cx),
                 suggestions_style: HighlightStyle {
                     color: Some(cx.theme().status().predictive),
                     ..HighlightStyle::default()

crates/editor/src/hover_links.rs 🔗

@@ -1205,6 +1205,7 @@ mod tests {
                 show_type_hints: true,
                 show_parameter_hints: true,
                 show_other_hints: true,
+                show_background: false,
             })
         });
 

crates/editor/src/inlay_hint_cache.rs 🔗

@@ -1296,6 +1296,7 @@ pub mod tests {
                 show_type_hints: allowed_hint_kinds.contains(&Some(InlayHintKind::Type)),
                 show_parameter_hints: allowed_hint_kinds.contains(&Some(InlayHintKind::Parameter)),
                 show_other_hints: allowed_hint_kinds.contains(&None),
+                show_background: false,
             })
         });
 
@@ -1428,6 +1429,7 @@ pub mod tests {
                 show_type_hints: true,
                 show_parameter_hints: true,
                 show_other_hints: true,
+                show_background: false,
             })
         });
 
@@ -1547,6 +1549,7 @@ pub mod tests {
                 show_type_hints: true,
                 show_parameter_hints: true,
                 show_other_hints: true,
+                show_background: false,
             })
         });
 
@@ -1777,6 +1780,7 @@ pub mod tests {
                 show_type_hints: allowed_hint_kinds.contains(&Some(InlayHintKind::Type)),
                 show_parameter_hints: allowed_hint_kinds.contains(&Some(InlayHintKind::Parameter)),
                 show_other_hints: allowed_hint_kinds.contains(&None),
+                show_background: false,
             })
         });
 
@@ -1941,6 +1945,7 @@ pub mod tests {
                     show_parameter_hints: new_allowed_hint_kinds
                         .contains(&Some(InlayHintKind::Parameter)),
                     show_other_hints: new_allowed_hint_kinds.contains(&None),
+                    show_background: false,
                 })
             });
             cx.executor().run_until_parked();
@@ -1987,6 +1992,7 @@ pub mod tests {
                 show_parameter_hints: another_allowed_hint_kinds
                     .contains(&Some(InlayHintKind::Parameter)),
                 show_other_hints: another_allowed_hint_kinds.contains(&None),
+                show_background: false,
             })
         });
         cx.executor().run_until_parked();
@@ -2047,6 +2053,7 @@ pub mod tests {
                 show_parameter_hints: final_allowed_hint_kinds
                     .contains(&Some(InlayHintKind::Parameter)),
                 show_other_hints: final_allowed_hint_kinds.contains(&None),
+                show_background: false,
             })
         });
         cx.executor().run_until_parked();
@@ -2122,6 +2129,7 @@ pub mod tests {
                 show_type_hints: true,
                 show_parameter_hints: true,
                 show_other_hints: true,
+                show_background: false,
             })
         });
 
@@ -2256,6 +2264,7 @@ pub mod tests {
                 show_type_hints: true,
                 show_parameter_hints: true,
                 show_other_hints: true,
+                show_background: false,
             })
         });
 
@@ -2551,6 +2560,7 @@ pub mod tests {
                 show_type_hints: true,
                 show_parameter_hints: true,
                 show_other_hints: true,
+                show_background: false,
             })
         });
 
@@ -2902,6 +2912,7 @@ pub mod tests {
                 show_type_hints: false,
                 show_parameter_hints: false,
                 show_other_hints: false,
+                show_background: false,
             })
         });
 
@@ -3096,6 +3107,7 @@ pub mod tests {
                 show_type_hints: true,
                 show_parameter_hints: true,
                 show_other_hints: true,
+                show_background: false,
             })
         });
         cx.executor().run_until_parked();
@@ -3131,6 +3143,7 @@ pub mod tests {
                 show_type_hints: true,
                 show_parameter_hints: true,
                 show_other_hints: true,
+                show_background: false,
             })
         });
 
@@ -3225,6 +3238,7 @@ pub mod tests {
                 show_type_hints: true,
                 show_parameter_hints: true,
                 show_other_hints: true,
+                show_background: false,
             })
         });
 
@@ -3305,6 +3319,7 @@ pub mod tests {
                 show_type_hints: true,
                 show_parameter_hints: true,
                 show_other_hints: true,
+                show_background: false,
             })
         });
         cx.executor().run_until_parked();

crates/language/src/language_settings.rs 🔗

@@ -741,6 +741,14 @@ pub struct InlayHintSettings {
     /// Default: true
     #[serde(default = "default_true")]
     pub show_other_hints: bool,
+    /// Whether to show a background for inlay hints.
+    ///
+    /// If set to `true`, the background will use the `hint.background` color
+    /// from the current theme.
+    ///
+    /// Default: false
+    #[serde(default)]
+    pub show_background: bool,
     /// Whether or not to debounce inlay hints updates after buffer edits.
     ///
     /// Set to 0 to disable debouncing.

docs/src/configuring-zed.md 🔗

@@ -982,6 +982,7 @@ To interpret all `.c` files as C++, files called `MyLockFile` as TOML and files
   "show_type_hints": true,
   "show_parameter_hints": true,
   "show_other_hints": true,
+  "show_background": false,
   "edit_debounce_ms": 700,
   "scroll_debounce_ms": 50
 }