From b38f75dcce8440f2110c4e4ba31ffbe6726bb1a2 Mon Sep 17 00:00:00 2001 From: Lori Holden Date: Mon, 27 Jul 2026 06:34:57 -0400 Subject: [PATCH] Add agent panel font family settings (#59629) Objective: Allow users to configure the font families used by agent panel content separately from the main UI and buffer fonts. Solution: - Add `agent_ui_font_family` for agent responses in the agent panel. - Add `agent_buffer_font_family` for the agent panel message editor and user messages. - Keep context menus on the primary UI font family. - Document the new settings and expose them in the settings UI. Testing: - Ran `cargo fmt`. - Ran `cargo check -p settings_content -p theme_settings -p markdown -p agent_ui -p settings_ui -p ui`. - Ran `git diff --check`. - Manually tested the agent panel font behavior in a dev build. Release Notes: - Added settings for configuring agent panel UI and buffer font families. Co-authored-by: Finn Evers --- assets/settings/default.json | 4 ++ crates/agent_ui/src/agent_panel.rs | 4 +- .../src/conversation_view/thread_view.rs | 2 +- crates/agent_ui/src/message_editor.rs | 2 +- crates/markdown/src/markdown.rs | 16 +++---- crates/settings/src/vscode_import.rs | 2 + crates/settings_content/src/theme.rs | 4 ++ crates/settings_ui/src/page_data.rs | 42 ++++++++++++++++++- crates/theme_settings/src/settings.rs | 26 ++++++++++++ crates/ui/src/components/context_menu.rs | 6 ++- docs/src/visual-customization.md | 20 ++++++--- 11 files changed, 109 insertions(+), 19 deletions(-) diff --git a/assets/settings/default.json b/assets/settings/default.json index 98f758c9f3..24cc904112 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -69,8 +69,12 @@ "ui_font_weight": 400, // The default font size for text in the UI "ui_font_size": 16, + // The font family for agent responses in the agent panel. Falls back to the UI font family if unset. + "agent_ui_font_family": null, // The default font size for agent responses in the agent panel. Falls back to the UI font size if unset. "agent_ui_font_size": null, + // The font family for user messages in the agent panel. Falls back to the buffer font family if unset. + "agent_buffer_font_family": null, // The default font size for user messages in the agent panel. "agent_buffer_font_size": 12, // The default font size for the commit editor in the git panel and commit modal. diff --git a/crates/agent_ui/src/agent_panel.rs b/crates/agent_ui/src/agent_panel.rs index 72f99f3d6b..51bf65207f 100644 --- a/crates/agent_ui/src/agent_panel.rs +++ b/crates/agent_ui/src/agent_panel.rs @@ -6516,8 +6516,10 @@ impl Render for AgentPanel { match self.visible_font_size() { WhichFontSize::AgentFont => { - WithRemSize::new(ThemeSettings::get_global(cx).agent_ui_font_size(cx)) + let theme_settings = ThemeSettings::get_global(cx); + WithRemSize::new(theme_settings.agent_ui_font_size(cx)) .size_full() + .font_family(theme_settings.agent_ui_font_family().clone()) .child(content) .into_any() } diff --git a/crates/agent_ui/src/conversation_view/thread_view.rs b/crates/agent_ui/src/conversation_view/thread_view.rs index d1e90180fc..718513a9cc 100644 --- a/crates/agent_ui/src/conversation_view/thread_view.rs +++ b/crates/agent_ui/src/conversation_view/thread_view.rs @@ -7695,7 +7695,7 @@ impl ThreadView { .unwrap_or(&command_source) .to_string(); - let mut style = MarkdownStyle::themed(MarkdownFont::Agent, window, cx).with_buffer_font(cx); + let mut style = MarkdownStyle::themed(MarkdownFont::Agent, window, cx); style.container_style.text.font_size = Some(rems_from_px(12.).into()); style.container_style.text.line_height = Some(rems_from_px(17.).into()); style.height_is_multiple_of_line_height = true; diff --git a/crates/agent_ui/src/message_editor.rs b/crates/agent_ui/src/message_editor.rs index 61ccdc07f5..fe10a36cb9 100644 --- a/crates/agent_ui/src/message_editor.rs +++ b/crates/agent_ui/src/message_editor.rs @@ -2019,7 +2019,7 @@ impl Render for MessageEditor { let text_style = TextStyle { color: cx.theme().colors().text, - font_family: settings.buffer_font.family.clone(), + font_family: settings.agent_buffer_font_family().clone(), font_fallbacks: settings.buffer_font.fallbacks.clone(), font_features: settings.buffer_font.features.clone(), font_size: settings.agent_buffer_font_size(cx).into(), diff --git a/crates/markdown/src/markdown.rs b/crates/markdown/src/markdown.rs index 6134c41049..92921b58c3 100644 --- a/crates/markdown/src/markdown.rs +++ b/crates/markdown/src/markdown.rs @@ -188,15 +188,15 @@ impl MarkdownStyle { ), }; - let body_font_family = if is_preview { - theme_settings.markdown_preview_font_family().clone() - } else { - theme_settings.ui_font.family.clone() + let body_font_family = match font { + MarkdownFont::Preview => theme_settings.markdown_preview_font_family().clone(), + MarkdownFont::Agent => theme_settings.agent_ui_font_family().clone(), + MarkdownFont::Editor => theme_settings.ui_font.family.clone(), }; - let code_font_family = if is_preview { - theme_settings.markdown_preview_code_font_family().clone() - } else { - theme_settings.buffer_font.family.clone() + let code_font_family = match font { + MarkdownFont::Preview => theme_settings.markdown_preview_code_font_family().clone(), + MarkdownFont::Agent => theme_settings.agent_ui_font_family().clone(), + MarkdownFont::Editor => theme_settings.buffer_font.family.clone(), }; let mut text_style = window.text_style(); diff --git a/crates/settings/src/vscode_import.rs b/crates/settings/src/vscode_import.rs index 6db45b1e29..24072a291b 100644 --- a/crates/settings/src/vscode_import.rs +++ b/crates/settings/src/vscode_import.rs @@ -993,7 +993,9 @@ impl VsCodeSettings { buffer_font_weight: self.read_f32("editor.fontWeight").map(FontWeightContent), buffer_line_height: None, buffer_font_features: None, + agent_ui_font_family: None, agent_ui_font_size: None, + agent_buffer_font_family: None, agent_buffer_font_size: None, git_commit_buffer_font_size: None, markdown_preview_font_family: None, diff --git a/crates/settings_content/src/theme.rs b/crates/settings_content/src/theme.rs index 406c1ead91..fbfc941d36 100644 --- a/crates/settings_content/src/theme.rs +++ b/crates/settings_content/src/theme.rs @@ -145,8 +145,12 @@ pub struct ThemeSettingsContent { /// The OpenType features to enable for rendering in text buffers. #[schemars(default = "default_font_features")] pub buffer_font_features: Option, + /// The name of a font to use for agent responses in the agent panel. Falls back to the UI font if unset. + pub agent_ui_font_family: Option, /// The font size for agent responses in the agent panel. Falls back to the UI font size if unset. pub agent_ui_font_size: Option, + /// The name of a font to use for user messages in the agent panel. Falls back to the buffer font if unset. + pub agent_buffer_font_family: Option, /// The font size for user messages in the agent panel. pub agent_buffer_font_size: Option, pub git_commit_buffer_font_size: Option, diff --git a/crates/settings_ui/src/page_data.rs b/crates/settings_ui/src/page_data.rs index 8c2c9b20c5..941358fcb1 100644 --- a/crates/settings_ui/src/page_data.rs +++ b/crates/settings_ui/src/page_data.rs @@ -1130,9 +1130,29 @@ fn appearance_page() -> SettingsPage { ] } - fn agent_panel_font_section() -> [SettingsPageItem; 3] { + fn agent_panel_font_section() -> [SettingsPageItem; 5] { [ SettingsPageItem::SectionHeader("Agent Panel Font"), + SettingsPageItem::SettingItem(SettingItem { + title: "UI Font Family", + description: "Font family for agent response text in the agent panel. Falls back to the regular UI font family.", + field: Box::new(SettingField { + organization_override: None, + json_path: Some("agent_ui_font_family"), + pick: |settings_content| { + settings_content + .theme + .agent_ui_font_family + .as_ref() + .or(settings_content.theme.ui_font_family.as_ref()) + }, + write: |settings_content, value, _| { + settings_content.theme.agent_ui_font_family = value; + }, + }), + metadata: None, + files: USER, + }), SettingsPageItem::SettingItem(SettingItem { title: "UI Font Size", description: "Font size for agent response text in the agent panel. Falls back to the regular UI font size.", @@ -1153,6 +1173,26 @@ fn appearance_page() -> SettingsPage { metadata: None, files: USER, }), + SettingsPageItem::SettingItem(SettingItem { + title: "Buffer Font Family", + description: "Font family for user messages in the agent panel. Falls back to the regular buffer font family.", + field: Box::new(SettingField { + organization_override: None, + json_path: Some("agent_buffer_font_family"), + pick: |settings_content| { + settings_content + .theme + .agent_buffer_font_family + .as_ref() + .or(settings_content.theme.buffer_font_family.as_ref()) + }, + write: |settings_content, value, _| { + settings_content.theme.agent_buffer_font_family = value; + }, + }), + metadata: None, + files: USER, + }), SettingsPageItem::SettingItem(SettingItem { title: "Buffer Font Size", description: "Font size for user messages text in the agent panel.", diff --git a/crates/theme_settings/src/settings.rs b/crates/theme_settings/src/settings.rs index 517367af2b..68812368d9 100644 --- a/crates/theme_settings/src/settings.rs +++ b/crates/theme_settings/src/settings.rs @@ -52,8 +52,14 @@ pub struct ThemeSettings { /// /// The terminal font family can be overridden using it's own setting. pub buffer_font: Font, + /// The agent UI font family. Determines the family of response text in the agent panel. + /// Falls back to the UI font family if unset. + agent_ui_font_family: Option, /// The agent font size. Determines the size of text in the agent panel. Falls back to the UI font size if unset. agent_ui_font_size: Option, + /// The agent buffer font family. Determines the family of user messages in the agent panel. + /// Falls back to the buffer font family if unset. + agent_buffer_font_family: Option, /// The agent buffer font size. Determines the size of user messages in the agent panel. agent_buffer_font_size: Option, git_commit_buffer_font_size: Option, @@ -416,6 +422,12 @@ impl ThemeSettings { .unwrap_or_else(|| self.ui_font_size(cx)) } + pub fn agent_ui_font_family(&self) -> &SharedString { + self.agent_ui_font_family + .as_ref() + .unwrap_or(&self.ui_font.family) + } + /// Returns the agent panel buffer font size. pub fn agent_buffer_font_size(&self, cx: &App) -> Pixels { cx.try_global::() @@ -425,6 +437,12 @@ impl ThemeSettings { .unwrap_or_else(|| self.buffer_font_size(cx)) } + pub fn agent_buffer_font_family(&self) -> &SharedString { + self.agent_buffer_font_family + .as_ref() + .unwrap_or(&self.buffer_font.family) + } + pub fn git_commit_buffer_font_size(&self, cx: &App) -> Pixels { cx.try_global::() .map(|size| size.0) @@ -737,7 +755,15 @@ impl settings::Settings for ThemeSettings { }, buffer_font_size: clamp_font_size(content.buffer_font_size.unwrap().into_gpui()), buffer_line_height: content.buffer_line_height.unwrap().into(), + agent_ui_font_family: content + .agent_ui_font_family + .as_ref() + .map(|font| font.0.clone().into()), agent_ui_font_size: content.agent_ui_font_size.map(|s| s.into_gpui()), + agent_buffer_font_family: content + .agent_buffer_font_family + .as_ref() + .map(|font| font.0.clone().into()), agent_buffer_font_size: content.agent_buffer_font_size.map(|s| s.into_gpui()), git_commit_buffer_font_size: content.git_commit_buffer_font_size.map(|s| s.into_gpui()), markdown_preview_font_family: content diff --git a/crates/ui/src/components/context_menu.rs b/crates/ui/src/components/context_menu.rs index 3eedf11bc1..697cd87ca8 100644 --- a/crates/ui/src/components/context_menu.rs +++ b/crates/ui/src/components/context_menu.rs @@ -2191,7 +2191,9 @@ impl ContextMenuItem { impl Render for ContextMenu { fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { - let ui_font_size = theme::theme_settings(cx).ui_font_size(cx); + let theme_settings = theme::theme_settings(cx); + let ui_font_size = theme_settings.ui_font_size(cx); + let ui_font_family = theme_settings.ui_font(cx).family.clone(); let window_size = window.viewport_size(); let rem_size = window.rem_size(); let is_wide_window = window_size.width / rem_size > rems_from_px(800.).0; @@ -2241,6 +2243,7 @@ impl Render for ContextMenu { let render_aside = |aside: DocumentationAside, cx: &mut Context| { WithRemSize::new(ui_font_size) .occlude() + .font_family(ui_font_family.clone()) .elevation_2(cx) .w_full() .p_2() @@ -2267,6 +2270,7 @@ impl Render for ContextMenu { WithRemSize::new(ui_font_size) .occlude() + .font_family(ui_font_family.clone()) .elevation_2(cx) .flex() .flex_row() diff --git a/docs/src/visual-customization.md b/docs/src/visual-customization.md index a12399e605..a9d5a90bab 100644 --- a/docs/src/visual-customization.md +++ b/docs/src/visual-customization.md @@ -66,9 +66,14 @@ If you would like to use distinct themes for light mode/dark mode that can be se "line_height": "standard", }, - // Controls the font size for agent responses in the agent panel. - // If not specified, it falls back to the UI font size. + // Controls the font family and size for agent responses in the agent panel. + // If not specified, they fall back to the UI font family and size. + "agent_ui_font_family": "Inter", "agent_ui_font_size": 15, + // Controls the font family and size for the agent panel's message editor + // and user messages. + // If not specified, the font family falls back to the buffer font family. + "agent_buffer_font_family": "Berkeley Mono", // Controls the font size for the agent panel's message editor, user message, // and any other snippet of code. "agent_buffer_font_size": 12, @@ -514,11 +519,14 @@ Project panel can be shown/hidden with {#action project_panel::ToggleFocus} ({#k "default_width": 640, // Default width (left/right docked) "default_height": 320 // Default height (bottom docked) }, - // Controls the font size for agent responses in the agent panel. - // If not specified, it falls back to the UI font size. + // Controls the font family and size for agent responses in the agent panel. + // If not specified, they fall back to the UI font family and size. + "agent_ui_font_family": "Inter", "agent_ui_font_size": 15, - // Controls the font size for the agent panel's message editor, user message, - // and any other snippet of code. + // Controls the font family and size for the agent panel's message editor + // and user messages. + // If not specified, the font family falls back to the buffer font family. + "agent_buffer_font_family": "Berkeley Mono", "agent_buffer_font_size": 12 } ```