From f499504b1377e2cc859b5925ede93d27db812bc4 Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Fri, 3 Oct 2025 14:23:23 -0300 Subject: [PATCH] agent: Introduce `agent_buffer_font_size` setting (#39468) Closes https://github.com/zed-industries/zed/issues/39406 Follow up to https://github.com/zed-industries/zed/pull/38726 This PR introduces the `agent_buffer_font_size` setting and renames `agent_font_size` to `agent_ui_font_size`. This allows whoever wants `buffer_font_size` and `agent_buffer_font_size` to match, as well as folks who want a slightly smaller size only in the agent panel (which... also looks just better by default!). Release Notes: - agent: Introduced the `agent_buffer_font_size` setting and renamed `agent_font_size` to `agent_ui_font_size`, allowing for granular buffer font size control in the agent panel vs. regular editors. --- assets/settings/default.json | 8 ++- crates/agent_ui/src/acp/entry_view_state.rs | 4 +- crates/agent_ui/src/acp/message_editor.rs | 2 +- crates/agent_ui/src/acp/thread_view.rs | 8 +-- crates/agent_ui/src/agent_panel.rs | 16 ++--- crates/assistant_tools/src/edit_file_tool.rs | 2 +- crates/migrator/src/migrations.rs | 6 ++ .../src/migrations/m_2025_10_03/settings.rs | 30 +++++++++ crates/migrator/src/migrator.rs | 8 +++ crates/settings/src/settings_content/theme.rs | 7 +- crates/theme/src/settings.rs | 64 +++++++++++++++---- crates/theme/src/theme.rs | 23 +++++-- 12 files changed, 138 insertions(+), 40 deletions(-) create mode 100644 crates/migrator/src/migrations/m_2025_10_03/settings.rs diff --git a/assets/settings/default.json b/assets/settings/default.json index 52f2973b2b29ddb5af9297eb20239d47c61a66bd..561ca0c5663ee0a341abcc40bbd6e1d58a065fc8 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -74,8 +74,10 @@ "ui_font_weight": 400, // The default font size for text in the UI "ui_font_size": 16, - // The default font size for text in the agent panel. Falls back to the UI font size if unset. - "agent_font_size": 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 default font size for user messages in the agent panel. Falls back to the buffer font size if unset. + "agent_buffer_font_size": 12, // How much to fade out unused code. "unnecessary_code_fade": 0.3, // Active pane styling settings. @@ -2032,7 +2034,7 @@ // Examples: // "profiles": { // "Presenting": { - // "agent_font_size": 20.0, + // "agent_ui_font_size": 20.0, // "buffer_font_size": 20.0, // "theme": "One Light", // "ui_font_size": 20.0 diff --git a/crates/agent_ui/src/acp/entry_view_state.rs b/crates/agent_ui/src/acp/entry_view_state.rs index 0d4dfb0c206a78b2af932d5f3ef7d57c9bfbfc16..340b7f27e911276b4d65fce6124fea14576bda94 100644 --- a/crates/agent_ui/src/acp/entry_view_state.rs +++ b/crates/agent_ui/src/acp/entry_view_state.rs @@ -203,7 +203,7 @@ impl EntryViewState { self.entries.drain(range); } - pub fn agent_font_size_changed(&mut self, cx: &mut App) { + pub fn agent_ui_font_size_changed(&mut self, cx: &mut App) { for entry in self.entries.iter() { match entry { Entry::UserMessage { .. } | Entry::AssistantMessage { .. } => {} @@ -387,7 +387,7 @@ fn diff_editor_text_style_refinement(cx: &mut App) -> TextStyleRefinement { font_size: Some( TextSize::Small .rems(cx) - .to_pixels(ThemeSettings::get_global(cx).agent_font_size(cx)) + .to_pixels(ThemeSettings::get_global(cx).agent_ui_font_size(cx)) .into(), ), ..Default::default() diff --git a/crates/agent_ui/src/acp/message_editor.rs b/crates/agent_ui/src/acp/message_editor.rs index 0d7e6d02b1a2541cecc9013aa5cb9ce4dfbbe3ba..578841859aeaa8334fd0e8421c906e0d9bcbe280 100644 --- a/crates/agent_ui/src/acp/message_editor.rs +++ b/crates/agent_ui/src/acp/message_editor.rs @@ -1299,7 +1299,7 @@ impl Render for MessageEditor { font_family: settings.buffer_font.family.clone(), font_fallbacks: settings.buffer_font.fallbacks.clone(), font_features: settings.buffer_font.features.clone(), - font_size: settings.buffer_font_size(cx).into(), + font_size: settings.agent_buffer_font_size(cx).into(), line_height: relative(settings.buffer_line_height.value()), ..Default::default() }; diff --git a/crates/agent_ui/src/acp/thread_view.rs b/crates/agent_ui/src/acp/thread_view.rs index 4c1e51a3f3d706b2fb48ffc437db0725976c5aab..1f156376c596159816fdb6edfcc53efed5c9e24c 100644 --- a/crates/agent_ui/src/acp/thread_view.rs +++ b/crates/agent_ui/src/acp/thread_view.rs @@ -381,8 +381,8 @@ impl AcpThreadView { }); let subscriptions = [ - cx.observe_global_in::(window, Self::agent_font_size_changed), - cx.observe_global_in::(window, Self::agent_font_size_changed), + cx.observe_global_in::(window, Self::agent_ui_font_size_changed), + cx.observe_global_in::(window, Self::agent_ui_font_size_changed), cx.subscribe_in(&message_editor, window, Self::handle_message_editor_event), cx.subscribe_in(&entry_view_state, window, Self::handle_entry_view_event), ]; @@ -4902,9 +4902,9 @@ impl AcpThreadView { ) } - fn agent_font_size_changed(&mut self, _window: &mut Window, cx: &mut Context) { + fn agent_ui_font_size_changed(&mut self, _window: &mut Window, cx: &mut Context) { self.entry_view_state.update(cx, |entry_view_state, cx| { - entry_view_state.agent_font_size_changed(cx); + entry_view_state.agent_ui_font_size_changed(cx); }); } diff --git a/crates/agent_ui/src/agent_panel.rs b/crates/agent_ui/src/agent_panel.rs index 58ab2f5373bf2fc7d9cd013f62ed50959074ea03..1384af1081005399fed6cb22f99e6ec34812df8b 100644 --- a/crates/agent_ui/src/agent_panel.rs +++ b/crates/agent_ui/src/agent_panel.rs @@ -1108,15 +1108,15 @@ impl AgentPanel { WhichFontSize::AgentFont => { if persist { update_settings_file(self.fs.clone(), cx, move |settings, cx| { - let agent_font_size = - ThemeSettings::get_global(cx).agent_font_size(cx) + delta; + let agent_ui_font_size = + ThemeSettings::get_global(cx).agent_ui_font_size(cx) + delta; let _ = settings .theme - .agent_font_size - .insert(theme::clamp_font_size(agent_font_size).into()); + .agent_ui_font_size + .insert(theme::clamp_font_size(agent_ui_font_size).into()); }); } else { - theme::adjust_agent_font_size(cx, |size| size + delta); + theme::adjust_agent_ui_font_size(cx, |size| size + delta); } } WhichFontSize::BufferFont => { @@ -1136,10 +1136,10 @@ impl AgentPanel { ) { if action.persist { update_settings_file(self.fs.clone(), cx, move |settings, _| { - settings.theme.agent_font_size = None; + settings.theme.agent_ui_font_size = None; }); } else { - theme::reset_agent_font_size(cx); + theme::reset_agent_ui_font_size(cx); } } @@ -2570,7 +2570,7 @@ impl Render for AgentPanel { match self.active_view.which_font_size_used() { WhichFontSize::AgentFont => { - WithRemSize::new(ThemeSettings::get_global(cx).agent_font_size(cx)) + WithRemSize::new(ThemeSettings::get_global(cx).agent_ui_font_size(cx)) .size_full() .child(content) .into_any() diff --git a/crates/assistant_tools/src/edit_file_tool.rs b/crates/assistant_tools/src/edit_file_tool.rs index 74b156a73043fd061053f3d81d7ae88754d1f2d0..f88978650a32cdc6922a1ff864b0ee898721df80 100644 --- a/crates/assistant_tools/src/edit_file_tool.rs +++ b/crates/assistant_tools/src/edit_file_tool.rs @@ -1003,7 +1003,7 @@ impl ToolCard for EditFileToolCard { font_size: Some( TextSize::Small .rems(cx) - .to_pixels(ThemeSettings::get_global(cx).agent_font_size(cx)) + .to_pixels(ThemeSettings::get_global(cx).agent_ui_font_size(cx)) .into(), ), ..TextStyleRefinement::default() diff --git a/crates/migrator/src/migrations.rs b/crates/migrator/src/migrations.rs index c0b54b0afc3c74a23026100b706fd68d3476aff3..ca125ff5e8726ce9e63ab11bab2643e9ce54378d 100644 --- a/crates/migrator/src/migrations.rs +++ b/crates/migrator/src/migrations.rs @@ -111,3 +111,9 @@ pub(crate) mod m_2025_10_02 { pub(crate) use settings::remove_formatters_on_save; } + +pub(crate) mod m_2025_10_03 { + mod settings; + + pub(crate) use settings::SETTINGS_PATTERNS; +} diff --git a/crates/migrator/src/migrations/m_2025_10_03/settings.rs b/crates/migrator/src/migrations/m_2025_10_03/settings.rs new file mode 100644 index 0000000000000000000000000000000000000000..47d15e8ddfa1bfd2c73c8e408579c901294903ee --- /dev/null +++ b/crates/migrator/src/migrations/m_2025_10_03/settings.rs @@ -0,0 +1,30 @@ +use std::ops::Range; +use tree_sitter::{Query, QueryMatch}; + +use crate::MigrationPatterns; +use crate::patterns::SETTINGS_ROOT_KEY_VALUE_PATTERN; + +pub const SETTINGS_PATTERNS: MigrationPatterns = + &[(SETTINGS_ROOT_KEY_VALUE_PATTERN, rename_agent_font_size)]; + +/// Renames the setting `agent_font_size` to `agent_ui_font_size` +fn rename_agent_font_size( + contents: &str, + mat: &QueryMatch, + query: &Query, +) -> Option<(Range, String)> { + let setting_capture_ix = query.capture_index_for_name("name")?; + + let setting_name_range = mat + .nodes_for_capture_index(setting_capture_ix) + .next()? + .byte_range(); + + let setting_name = contents.get(setting_name_range.clone())?; + + if setting_name != "agent_font_size" { + return None; + } + + Some((setting_name_range, "agent_ui_font_size".to_string())) +} diff --git a/crates/migrator/src/migrator.rs b/crates/migrator/src/migrator.rs index 4e649a0791fb0acef9d1b56138972964fd8ee3ac..74205edd8ace72c93e5ec718b7df056e5ada288f 100644 --- a/crates/migrator/src/migrator.rs +++ b/crates/migrator/src/migrator.rs @@ -200,6 +200,10 @@ pub fn migrate_settings(text: &str) -> Result> { &SETTINGS_QUERY_2025_10_01, ), MigrationType::Json(migrations::m_2025_10_02::remove_formatters_on_save), + MigrationType::TreeSitter( + migrations::m_2025_10_03::SETTINGS_PATTERNS, + &SETTINGS_QUERY_2025_10_03, + ), ]; run_migrations(text, migrations) } @@ -318,6 +322,10 @@ define_query!( SETTINGS_QUERY_2025_10_01, migrations::m_2025_10_01::SETTINGS_PATTERNS ); +define_query!( + SETTINGS_QUERY_2025_10_03, + migrations::m_2025_10_03::SETTINGS_PATTERNS +); // custom query static EDIT_PREDICTION_SETTINGS_MIGRATION_QUERY: LazyLock = LazyLock::new(|| { diff --git a/crates/settings/src/settings_content/theme.rs b/crates/settings/src/settings_content/theme.rs index 84dd9ce88820bd4820037d41eee0f9ded610da39..737de357009ff44e391784ae162ea3bfe782fec7 100644 --- a/crates/settings/src/settings_content/theme.rs +++ b/crates/settings/src/settings_content/theme.rs @@ -52,9 +52,12 @@ pub struct ThemeSettingsContent { #[serde(default)] #[schemars(default = "default_font_features")] pub buffer_font_features: Option, - /// The font size for the agent panel. Falls back to the UI font size if unset. + /// The font size for agent responses in the agent panel. Falls back to the UI font size if unset. #[serde(default)] - pub agent_font_size: Option, + pub agent_ui_font_size: Option, + /// The font size for user messages in the agent panel. Falls back to the buffer font size if unset. + #[serde(default)] + pub agent_buffer_font_size: Option, /// The name of the Zed theme to use. #[serde(default)] pub theme: Option, diff --git a/crates/theme/src/settings.rs b/crates/theme/src/settings.rs index 04b8bd3dd7c597b8730c03f1ed8ac9fdb83929d6..c26fe0339a226a61a57365dfcee3cf360ccaf458 100644 --- a/crates/theme/src/settings.rs +++ b/crates/theme/src/settings.rs @@ -115,7 +115,9 @@ pub struct ThemeSettings { /// The terminal font family can be overridden using it's own setting. pub buffer_font: Font, /// The agent font size. Determines the size of text in the agent panel. Falls back to the UI font size if unset. - agent_font_size: Option, + agent_ui_font_size: Option, + /// The agent buffer font size. Determines the size of user messages in the agent panel. Falls back to the buffer font size if unset. + agent_buffer_font_size: Option, /// The line height for buffers, and the terminal. /// /// Changing this may affect the spacing of some UI elements. @@ -539,14 +541,23 @@ impl ThemeSettings { } /// Returns the agent panel font size. Falls back to the UI font size if unset. - pub fn agent_font_size(&self, cx: &App) -> Pixels { + pub fn agent_ui_font_size(&self, cx: &App) -> Pixels { cx.try_global::() .map(|size| size.0) - .or(self.agent_font_size) + .or(self.agent_ui_font_size) .map(clamp_font_size) .unwrap_or_else(|| self.ui_font_size(cx)) } + /// Returns the agent panel buffer font size. Falls back to the buffer font size if unset. + pub fn agent_buffer_font_size(&self, cx: &App) -> Pixels { + cx.try_global::() + .map(|size| size.0) + .or(self.agent_buffer_font_size) + .map(clamp_font_size) + .unwrap_or_else(|| self.buffer_font_size(cx)) + } + /// Returns the buffer font size, read from the settings. /// /// The real buffer font size is stored in-memory, to support temporary font size changes. @@ -566,9 +577,17 @@ impl ThemeSettings { /// Returns the agent font size, read from the settings. /// /// The real agent font size is stored in-memory, to support temporary font size changes. - /// Use [`Self::agent_font_size`] to get the real font size. - pub fn agent_font_size_settings(&self) -> Option { - self.agent_font_size + /// Use [`Self::agent_ui_font_size`] to get the real font size. + pub fn agent_ui_font_size_settings(&self) -> Option { + self.agent_ui_font_size + } + + /// Returns the agent buffer font size, read from the settings. + /// + /// The real agent buffer font size is stored in-memory, to support temporary font size changes. + /// Use [`Self::agent_buffer_font_size`] to get the real font size. + pub fn agent_buffer_font_size_settings(&self) -> Option { + self.agent_buffer_font_size } // TODO: Rename: `line_height` -> `buffer_line_height` @@ -725,18 +744,36 @@ pub fn reset_ui_font_size(cx: &mut App) { } } -/// Sets the adjusted agent panel font size. -pub fn adjust_agent_font_size(cx: &mut App, f: impl FnOnce(Pixels) -> Pixels) { - let agent_font_size = ThemeSettings::get_global(cx).agent_font_size(cx); +/// Sets the adjusted font size of agent responses in the agent panel. +pub fn adjust_agent_ui_font_size(cx: &mut App, f: impl FnOnce(Pixels) -> Pixels) { + let agent_ui_font_size = ThemeSettings::get_global(cx).agent_ui_font_size(cx); + let adjusted_size = cx + .try_global::() + .map_or(agent_ui_font_size, |adjusted_size| adjusted_size.0); + cx.set_global(AgentFontSize(clamp_font_size(f(adjusted_size)))); + cx.refresh_windows(); +} + +/// Resets the agent response font size in the agent panel to the default value. +pub fn reset_agent_ui_font_size(cx: &mut App) { + if cx.has_global::() { + cx.remove_global::(); + cx.refresh_windows(); + } +} + +/// Sets the adjusted font size of user messages in the agent panel. +pub fn adjust_agent_buffer_font_size(cx: &mut App, f: impl FnOnce(Pixels) -> Pixels) { + let agent_buffer_font_size = ThemeSettings::get_global(cx).agent_buffer_font_size(cx); let adjusted_size = cx .try_global::() - .map_or(agent_font_size, |adjusted_size| adjusted_size.0); + .map_or(agent_buffer_font_size, |adjusted_size| adjusted_size.0); cx.set_global(AgentFontSize(clamp_font_size(f(adjusted_size)))); cx.refresh_windows(); } -/// Resets the agent panel font size to the default value. -pub fn reset_agent_font_size(cx: &mut App) { +/// Resets the user message font size in the agent panel to the default value. +pub fn reset_agent_buffer_font_size(cx: &mut App) { if cx.has_global::() { cx.remove_global::(); cx.refresh_windows(); @@ -798,7 +835,8 @@ impl settings::Settings for ThemeSettings { }, buffer_font_size: clamp_font_size(content.buffer_font_size.unwrap().into()), buffer_line_height: content.buffer_line_height.unwrap().into(), - agent_font_size: content.agent_font_size.map(Into::into), + agent_ui_font_size: content.agent_ui_font_size.map(Into::into), + agent_buffer_font_size: content.agent_buffer_font_size.map(Into::into), active_theme: themes .get(theme_selection.theme(*system_appearance)) .or(themes.get(&zed_default_dark().name)) diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index 29269c15074a158acd742c7f6e258b0c94b7bebe..5b12e4d33bd5f2eb7ad3500e9194363de47b356f 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -111,8 +111,11 @@ pub fn init(themes_to_load: LoadThemes, cx: &mut App) { let mut prev_buffer_font_size_settings = ThemeSettings::get_global(cx).buffer_font_size_settings(); let mut prev_ui_font_size_settings = ThemeSettings::get_global(cx).ui_font_size_settings(); - let mut prev_agent_font_size_settings = - ThemeSettings::get_global(cx).agent_font_size_settings(); + let mut prev_agent_ui_font_size_settings = + ThemeSettings::get_global(cx).agent_ui_font_size_settings(); + let mut prev_agent_buffer_font_size_settings = + ThemeSettings::get_global(cx).agent_buffer_font_size_settings(); + cx.observe_global::(move |cx| { let buffer_font_size_settings = ThemeSettings::get_global(cx).buffer_font_size_settings(); if buffer_font_size_settings != prev_buffer_font_size_settings { @@ -126,10 +129,18 @@ pub fn init(themes_to_load: LoadThemes, cx: &mut App) { reset_ui_font_size(cx); } - let agent_font_size_settings = ThemeSettings::get_global(cx).agent_font_size_settings(); - if agent_font_size_settings != prev_agent_font_size_settings { - prev_agent_font_size_settings = agent_font_size_settings; - reset_agent_font_size(cx); + let agent_ui_font_size_settings = + ThemeSettings::get_global(cx).agent_ui_font_size_settings(); + if agent_ui_font_size_settings != prev_agent_ui_font_size_settings { + prev_agent_ui_font_size_settings = agent_ui_font_size_settings; + reset_agent_ui_font_size(cx); + } + + let agent_buffer_font_size_settings = + ThemeSettings::get_global(cx).agent_buffer_font_size_settings(); + if agent_buffer_font_size_settings != prev_agent_buffer_font_size_settings { + prev_agent_buffer_font_size_settings = agent_buffer_font_size_settings; + reset_agent_buffer_font_size(cx); } }) .detach();