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 <finn@zed.dev>
This commit is contained in:
Lori HoldenandFinn Evers authored and GitHub committed 2026-07-27 10:34:57 +00:00
1 parent 34eac8ff92
commit b38f75dcce
11 files changed
+109 -19

No files matched your search

+4
View File
@@ -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.
+3 -1
View File
@@ -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()
}
@@ -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;
+1 -1
View File
@@ -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(),
+8 -8
View File
@@ -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();
+2
View File
@@ -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,
+4
View File
@@ -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<FontFeaturesContent>,
/// 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<FontFamilyName>,
/// 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<FontSize>,
/// 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<FontFamilyName>,
/// The font size for user messages in the agent panel.
pub agent_buffer_font_size: Option<FontSize>,
pub git_commit_buffer_font_size: Option<FontSize>,
+41 -1
View File
@@ -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.",
+26
View File
@@ -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<SharedString>,
/// 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<Pixels>,
/// 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<SharedString>,
/// The agent buffer font size. Determines the size of user messages in the agent panel.
agent_buffer_font_size: Option<Pixels>,
git_commit_buffer_font_size: Option<Pixels>,
@@ -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::<AgentBufferFontSize>()
@@ -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::<GitCommitBufferFontSize>()
.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
+5 -1
View File
@@ -2191,7 +2191,9 @@ impl ContextMenuItem {
impl Render for ContextMenu {
fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> 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<Self>| {
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()
+14 -6
View File
@@ -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
}
```