Adds a way to toggle font size without settings adjustments (#24857)

Kirill Bulatov created

Closes https://github.com/zed-industries/zed/issues/23505

Now `zed::IncreaseBufferFontSize` (and all the same UI- and
Buffer-related settings) action is parameterized with `{ "persist": true
}` (default).
Using `"persist": false` brings back resizing behavior prior to
https://github.com/zed-industries/zed/pull/23265


Release Notes:

- Added a way to toggle font size without settings adjustments

Change summary

assets/keymaps/default-linux.json            |   8 
assets/keymaps/default-macos.json            |   8 
assets/keymaps/linux/jetbrains.json          |   4 
assets/keymaps/macos/jetbrains.json          |   4 
crates/assistant2/src/message_editor.rs      |   8 -
crates/editor/src/editor.rs                  |   8 +
crates/outline/src/outline.rs                |   2 
crates/repl/src/outputs/plain.rs             |   3 
crates/terminal_view/src/terminal_element.rs |   7 
crates/theme/src/settings.rs                 | 112 ++++++++++++++++++++-
crates/theme/src/theme.rs                    |  11 ++
crates/ui/src/styles/typography.rs           |   2 
crates/vim/src/vim.rs                        |  10 
crates/zed/src/zed.rs                        |  85 +++++++++------
crates/zed/src/zed/app_menus.rs              |  15 ++
crates/zed_actions/src/lib.rs                |  42 ++++++++
crates/zeta/src/completion_diff_element.rs   |   2 
17 files changed, 251 insertions(+), 80 deletions(-)

Detailed changes

assets/keymaps/default-linux.json 🔗

@@ -24,10 +24,10 @@
       "shift-escape": "workspace::ToggleZoom",
       "open": "workspace::Open",
       "ctrl-o": "workspace::Open",
-      "ctrl-=": "zed::IncreaseBufferFontSize",
-      "ctrl-+": "zed::IncreaseBufferFontSize",
-      "ctrl--": "zed::DecreaseBufferFontSize",
-      "ctrl-0": "zed::ResetBufferFontSize",
+      "ctrl-=": ["zed::IncreaseBufferFontSize", { "persist": true }],
+      "ctrl-+": ["zed::IncreaseBufferFontSize", { "persist": true }],
+      "ctrl--": ["zed::DecreaseBufferFontSize", { "persist": true }],
+      "ctrl-0": ["zed::ResetBufferFontSize", { "persist": true }],
       "ctrl-,": "zed::OpenSettings",
       "ctrl-q": "zed::Quit",
       "f11": "zed::ToggleFullScreen",

assets/keymaps/default-macos.json 🔗

@@ -28,10 +28,10 @@
       "cmd-shift-w": "workspace::CloseWindow",
       "shift-escape": "workspace::ToggleZoom",
       "cmd-o": "workspace::Open",
-      "cmd-=": "zed::IncreaseBufferFontSize",
-      "cmd-+": "zed::IncreaseBufferFontSize",
-      "cmd--": "zed::DecreaseBufferFontSize",
-      "cmd-0": "zed::ResetBufferFontSize",
+      "cmd-=": ["zed::IncreaseBufferFontSize", { "persist": true }],
+      "cmd-+": ["zed::IncreaseBufferFontSize", { "persist": true }],
+      "cmd--": ["zed::DecreaseBufferFontSize", { "persist": true }],
+      "cmd-0": ["zed::ResetBufferFontSize", { "persist": true }],
       "cmd-,": "zed::OpenSettings",
       "cmd-q": "zed::Quit",
       "cmd-h": "zed::Hide",

assets/keymaps/linux/jetbrains.json 🔗

@@ -9,8 +9,8 @@
   {
     "context": "Editor",
     "bindings": {
-      "ctrl->": "zed::IncreaseBufferFontSize",
-      "ctrl-<": "zed::DecreaseBufferFontSize",
+      "ctrl->": ["zed::IncreaseBufferFontSize", { "persist": true }],
+      "ctrl-<": ["zed::DecreaseBufferFontSize", { "persist": true }],
       "ctrl-shift-j": "editor::JoinLines",
       "ctrl-d": "editor::DuplicateSelection",
       "ctrl-y": "editor::DeleteLine",

assets/keymaps/macos/jetbrains.json 🔗

@@ -8,8 +8,8 @@
   {
     "context": "Editor",
     "bindings": {
-      "ctrl->": "zed::IncreaseBufferFontSize",
-      "ctrl-<": "zed::DecreaseBufferFontSize",
+      "ctrl->": ["zed::IncreaseBufferFontSize", { "persist": true }],
+      "ctrl-<": ["zed::DecreaseBufferFontSize", { "persist": true }],
       "ctrl-shift-j": "editor::JoinLines",
       "cmd-d": "editor::DuplicateSelection",
       "cmd-backspace": "editor::DeleteLine",

crates/assistant2/src/message_editor.rs 🔗

@@ -13,7 +13,7 @@ use rope::Point;
 use settings::Settings;
 use std::time::Duration;
 use text::Bias;
-use theme::ThemeSettings;
+use theme::{get_ui_font_size, ThemeSettings};
 use ui::{
     prelude::*, ButtonLike, KeyBinding, PopoverMenu, PopoverMenuHandle, Switch, TintColor, Tooltip,
 };
@@ -369,11 +369,7 @@ impl Render for MessageEditor {
                             .anchor(gpui::Corner::BottomLeft)
                             .offset(gpui::Point {
                                 x: px(0.0),
-                                y: px(-ThemeSettings::clamp_font_size(
-                                    ThemeSettings::get_global(cx).ui_font_size,
-                                )
-                                .0 * 2.0)
-                                    - px(4.0),
+                                y: (-get_ui_font_size(cx) * 2) - px(4.0),
                             })
                             .with_handle(self.inline_context_picker_menu_handle.clone()),
                     )

crates/editor/src/editor.rs 🔗

@@ -162,7 +162,10 @@ use std::{
 pub use sum_tree::Bias;
 use sum_tree::TreeMap;
 use text::{BufferId, OffsetUtf16, Rope};
-use theme::{ActiveTheme, PlayerColor, StatusColors, SyntaxTheme, ThemeColors, ThemeSettings};
+use theme::{
+    observe_buffer_font_size_adjustment, ActiveTheme, PlayerColor, StatusColors, SyntaxTheme,
+    ThemeColors, ThemeSettings,
+};
 use ui::{
     h_flex, prelude::*, ButtonSize, ButtonStyle, Disclosure, IconButton, IconName, IconSize, Key,
     Tooltip,
@@ -1454,6 +1457,7 @@ impl Editor {
                 cx.observe_in(&display_map, window, Self::on_display_map_changed),
                 cx.observe(&blink_manager, |_, _, cx| cx.notify()),
                 cx.observe_global_in::<SettingsStore>(window, Self::settings_changed),
+                observe_buffer_font_size_adjustment(cx, |_, cx| cx.notify()),
                 cx.observe_window_activation(window, |editor, window, cx| {
                     let active = window.is_window_active();
                     editor.blink_manager.update(cx, |blink_manager, cx| {
@@ -16143,7 +16147,7 @@ impl Render for Editor {
                 font_family: settings.buffer_font.family.clone(),
                 font_features: settings.buffer_font.features.clone(),
                 font_fallbacks: settings.buffer_font.fallbacks.clone(),
-                font_size: settings.buffer_font_size().into(),
+                font_size: settings.buffer_font_size(cx).into(),
                 font_weight: settings.buffer_font.weight,
                 line_height: relative(settings.buffer_line_height.value()),
                 ..Default::default()

crates/outline/src/outline.rs 🔗

@@ -349,7 +349,7 @@ pub fn render_item<T>(
         font_family: settings.buffer_font.family.clone(),
         font_features: settings.buffer_font.features.clone(),
         font_fallbacks: settings.buffer_font.fallbacks.clone(),
-        font_size: settings.buffer_font_size().into(),
+        font_size: settings.buffer_font_size(cx).into(),
         font_weight: settings.buffer_font.weight,
         line_height: relative(1.),
         ..Default::default()

crates/repl/src/outputs/plain.rs 🔗

@@ -59,7 +59,6 @@ const DEFAULT_NUM_COLUMNS: usize = 128;
 pub fn text_style(window: &mut Window, cx: &mut App) -> TextStyle {
     let settings = ThemeSettings::get_global(cx).clone();
 
-    let font_size = settings.buffer_font_size().into();
     let font_family = settings.buffer_font.family;
     let font_features = settings.buffer_font.features;
     let font_weight = settings.buffer_font.weight;
@@ -72,7 +71,7 @@ pub fn text_style(window: &mut Window, cx: &mut App) -> TextStyle {
         font_features,
         font_weight,
         font_fallbacks,
-        font_size,
+        font_size: theme::get_buffer_font_size(cx).into(),
         font_style: FontStyle::Normal,
         line_height: window.line_height().into(),
         background_color: Some(theme.colors().terminal_ansi_background),

crates/terminal_view/src/terminal_element.rs 🔗

@@ -555,7 +555,7 @@ impl TerminalElement {
 
     fn rem_size(&self, cx: &mut App) -> Option<Pixels> {
         let settings = ThemeSettings::get_global(cx).clone();
-        let buffer_font_size = settings.buffer_font_size();
+        let buffer_font_size = settings.buffer_font_size(cx);
         let rem_size_scale = {
             // Our default UI font size is 14px on a 16px base scale.
             // This means the default UI font size is 0.875rems.
@@ -619,7 +619,7 @@ impl Element for TerminalElement {
                 let hitbox = hitbox.unwrap();
                 let settings = ThemeSettings::get_global(cx).clone();
 
-                let buffer_font_size = settings.buffer_font_size();
+                let buffer_font_size = settings.buffer_font_size(cx);
 
                 let terminal_settings = TerminalSettings::get_global(cx);
 
@@ -646,7 +646,8 @@ impl Element for TerminalElement {
                 let line_height = terminal_settings.line_height.value();
                 let font_size = terminal_settings.font_size;
 
-                let font_size = font_size.unwrap_or(buffer_font_size);
+                let font_size =
+                    font_size.map_or(buffer_font_size, |size| theme::adjusted_font_size(size, cx));
 
                 let theme = cx.theme().clone();
 

crates/theme/src/settings.rs 🔗

@@ -6,7 +6,8 @@ use crate::{
 use anyhow::Result;
 use derive_more::{Deref, DerefMut};
 use gpui::{
-    px, App, Font, FontFallbacks, FontFeatures, FontStyle, FontWeight, Global, Pixels, Window,
+    px, App, Context, Font, FontFallbacks, FontFeatures, FontStyle, FontWeight, Global, Pixels,
+    Subscription, Window,
 };
 use refineable::Refineable;
 use schemars::{
@@ -234,6 +235,16 @@ impl SystemAppearance {
     }
 }
 
+#[derive(Default)]
+pub(crate) struct AdjustedBufferFontSize(Pixels);
+
+impl Global for AdjustedBufferFontSize {}
+
+#[derive(Default)]
+pub(crate) struct AdjustedUiFontSize(Pixels);
+
+impl Global for AdjustedUiFontSize {}
+
 /// Represents the selection of a theme, which can be either static or dynamic.
 #[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
 #[serde(untagged)]
@@ -545,13 +556,10 @@ impl BufferLineHeight {
 
 impl ThemeSettings {
     /// Returns the buffer font size.
-    pub fn buffer_font_size(&self) -> Pixels {
-        Self::clamp_font_size(self.buffer_font_size)
-    }
-
-    /// Ensures that the font size is within the valid range.
-    pub fn clamp_font_size(size: Pixels) -> Pixels {
-        size.max(MIN_FONT_SIZE)
+    pub fn buffer_font_size(&self, cx: &App) -> Pixels {
+        cx.try_global::<AdjustedBufferFontSize>()
+            .map_or(self.buffer_font_size, |size| size.0)
+            .max(MIN_FONT_SIZE)
     }
 
     // TODO: Rename: `line_height` -> `buffer_line_height`
@@ -626,19 +634,105 @@ impl ThemeSettings {
     }
 }
 
+/// Observe changes to the adjusted buffer font size.
+pub fn observe_buffer_font_size_adjustment<V: 'static>(
+    cx: &mut Context<V>,
+    f: impl 'static + Fn(&mut V, &mut Context<V>),
+) -> Subscription {
+    cx.observe_global::<AdjustedBufferFontSize>(f)
+}
+
+/// Sets the adjusted buffer font size.
+pub fn adjusted_font_size(size: Pixels, cx: &App) -> Pixels {
+    if let Some(AdjustedBufferFontSize(adjusted_size)) = cx.try_global::<AdjustedBufferFontSize>() {
+        let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
+        let delta = *adjusted_size - buffer_font_size;
+        size + delta
+    } else {
+        size
+    }
+    .max(MIN_FONT_SIZE)
+}
+
+/// Returns the adjusted buffer font size.
+pub fn get_buffer_font_size(cx: &App) -> Pixels {
+    let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
+    cx.try_global::<AdjustedBufferFontSize>()
+        .map_or(buffer_font_size, |adjusted_size| adjusted_size.0)
+}
+
+/// Adjusts the buffer font size.
+pub fn adjust_buffer_font_size(cx: &mut App, mut f: impl FnMut(&mut Pixels)) {
+    let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
+    let mut adjusted_size = cx
+        .try_global::<AdjustedBufferFontSize>()
+        .map_or(buffer_font_size, |adjusted_size| adjusted_size.0);
+
+    f(&mut adjusted_size);
+    adjusted_size = adjusted_size.max(MIN_FONT_SIZE);
+    cx.set_global(AdjustedBufferFontSize(adjusted_size));
+    cx.refresh_windows();
+}
+
+/// Returns whether the buffer font size has been adjusted.
+pub fn has_adjusted_buffer_font_size(cx: &App) -> bool {
+    cx.has_global::<AdjustedBufferFontSize>()
+}
+
+/// Resets the buffer font size to the default value.
+pub fn reset_buffer_font_size(cx: &mut App) {
+    if cx.has_global::<AdjustedBufferFontSize>() {
+        cx.remove_global::<AdjustedBufferFontSize>();
+        cx.refresh_windows();
+    }
+}
+
 // TODO: Make private, change usages to use `get_ui_font_size` instead.
 #[allow(missing_docs)]
 pub fn setup_ui_font(window: &mut Window, cx: &mut App) -> gpui::Font {
     let (ui_font, ui_font_size) = {
         let theme_settings = ThemeSettings::get_global(cx);
         let font = theme_settings.ui_font.clone();
-        (font, theme_settings.ui_font_size)
+        (font, get_ui_font_size(cx))
     };
 
     window.set_rem_size(ui_font_size);
     ui_font
 }
 
+/// Gets the adjusted UI font size.
+pub fn get_ui_font_size(cx: &App) -> Pixels {
+    let ui_font_size = ThemeSettings::get_global(cx).ui_font_size;
+    cx.try_global::<AdjustedUiFontSize>()
+        .map_or(ui_font_size, |adjusted_size| adjusted_size.0)
+}
+
+/// Sets the adjusted UI font size.
+pub fn adjust_ui_font_size(cx: &mut App, mut f: impl FnMut(&mut Pixels)) {
+    let ui_font_size = ThemeSettings::get_global(cx).ui_font_size;
+    let mut adjusted_size = cx
+        .try_global::<AdjustedUiFontSize>()
+        .map_or(ui_font_size, |adjusted_size| adjusted_size.0);
+
+    f(&mut adjusted_size);
+    adjusted_size = adjusted_size.max(MIN_FONT_SIZE);
+    cx.set_global(AdjustedUiFontSize(adjusted_size));
+    cx.refresh_windows();
+}
+
+/// Returns whether the UI font size has been adjusted.
+pub fn has_adjusted_ui_font_size(cx: &App) -> bool {
+    cx.has_global::<AdjustedUiFontSize>()
+}
+
+/// Resets the UI font size to the default value.
+pub fn reset_ui_font_size(cx: &mut App) {
+    if cx.has_global::<AdjustedUiFontSize>() {
+        cx.remove_global::<AdjustedUiFontSize>();
+        cx.refresh_windows();
+    }
+}
+
 fn clamp_font_weight(weight: f32) -> FontWeight {
     FontWeight(weight.clamp(100., 950.))
 }

crates/theme/src/theme.rs 🔗

@@ -23,6 +23,7 @@ use std::path::Path;
 use std::sync::Arc;
 
 use ::settings::Settings;
+use ::settings::SettingsStore;
 use anyhow::Result;
 use fallback_themes::apply_status_color_defaults;
 use fs::Fs;
@@ -101,6 +102,16 @@ pub fn init(themes_to_load: LoadThemes, cx: &mut App) {
 
     ThemeSettings::register(cx);
     FontFamilyCache::init_global(cx);
+
+    let mut prev_buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
+    cx.observe_global::<SettingsStore>(move |cx| {
+        let buffer_font_size = ThemeSettings::get_global(cx).buffer_font_size;
+        if buffer_font_size != prev_buffer_font_size {
+            prev_buffer_font_size = buffer_font_size;
+            reset_buffer_font_size(cx);
+        }
+    })
+    .detach();
 }
 
 /// Implementing this trait allows accessing the active theme.

crates/ui/src/styles/typography.rs 🔗

@@ -83,7 +83,7 @@ pub trait StyledTypography: Styled + Sized {
     /// or other places that text needs to match the user's buffer font size.
     fn text_buffer(self, cx: &App) -> Self {
         let settings = ThemeSettings::get_global(cx);
-        self.text_size(settings.buffer_font_size())
+        self.text_size(settings.buffer_font_size(cx))
     }
 }
 

crates/vim/src/vim.rs 🔗

@@ -215,7 +215,7 @@ pub fn init(cx: &mut App) {
             };
 
             let theme = ThemeSettings::get_global(cx);
-            let height = theme.buffer_font_size() * theme.buffer_line_height.value();
+            let height = theme.buffer_font_size(cx) * theme.buffer_line_height.value();
 
             let desired_size = if let Some(count) = Vim::take_count(cx) {
                 height * count
@@ -233,7 +233,7 @@ pub fn init(cx: &mut App) {
             };
             let Ok(width) = window
                 .text_system()
-                .advance(font_id, theme.buffer_font_size(), 'm')
+                .advance(font_id, theme.buffer_font_size(cx), 'm')
             else {
                 return;
             };
@@ -248,7 +248,7 @@ pub fn init(cx: &mut App) {
             };
             let Ok(width) = window
                 .text_system()
-                .advance(font_id, theme.buffer_font_size(), 'm')
+                .advance(font_id, theme.buffer_font_size(cx), 'm')
             else {
                 return;
             };
@@ -258,14 +258,14 @@ pub fn init(cx: &mut App) {
         workspace.register_action(|workspace, _: &ResizePaneUp, window, cx| {
             let count = Vim::take_count(cx).unwrap_or(1) as f32;
             let theme = ThemeSettings::get_global(cx);
-            let height = theme.buffer_font_size() * theme.buffer_line_height.value();
+            let height = theme.buffer_font_size(cx) * theme.buffer_line_height.value();
             workspace.resize_pane(Axis::Vertical, height * count, window, cx);
         });
 
         workspace.register_action(|workspace, _: &ResizePaneDown, window, cx| {
             let count = Vim::take_count(cx).unwrap_or(1) as f32;
             let theme = ThemeSettings::get_global(cx);
-            let height = theme.buffer_font_size() * theme.buffer_line_height.value();
+            let height = theme.buffer_font_size(cx) * theme.buffer_line_height.value();
             workspace.resize_pane(Axis::Vertical, -height * count, window, cx);
         });
 

crates/zed/src/zed.rs 🔗

@@ -540,65 +540,80 @@ fn register_actions(
         })
         .register_action({
             let fs = app_state.fs.clone();
-            move |_, _: &zed_actions::IncreaseUiFontSize, _window, cx| {
-                update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
-                    let buffer_font_size = ThemeSettings::clamp_font_size(
-                        ThemeSettings::get_global(cx).ui_font_size + px(1.),
-                    );
-
-                    let _ = settings.ui_font_size.insert(buffer_font_size.into());
+            move |_, action: &zed_actions::IncreaseUiFontSize, _window, cx| {
+                theme::adjust_ui_font_size(cx, |size| {
+                    *size += px(1.0);
                 });
+                if action.persist {
+                    update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
+                        let _ = settings.ui_font_size.insert(theme::get_ui_font_size(cx).0);
+                    });
+                }
             }
         })
         .register_action({
             let fs = app_state.fs.clone();
-            move |_, _: &zed_actions::DecreaseUiFontSize, _window, cx| {
-                update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
-                    let buffer_font_size = ThemeSettings::clamp_font_size(
-                        ThemeSettings::get_global(cx).ui_font_size - px(1.),
-                    );
-
-                    let _ = settings.ui_font_size.insert(buffer_font_size.into());
+            move |_, action: &zed_actions::DecreaseUiFontSize, _window, cx| {
+                theme::adjust_ui_font_size(cx, |size| {
+                    *size -= px(1.0);
                 });
+                if action.persist {
+                    update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
+                        let _ = settings.ui_font_size.insert(theme::get_ui_font_size(cx).0);
+                    });
+                }
             }
         })
         .register_action({
             let fs = app_state.fs.clone();
-            move |_, _: &zed_actions::ResetUiFontSize, _window, cx| {
-                update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, _| {
-                    let _ = settings.ui_font_size.take();
-                });
+            move |_, action: &zed_actions::ResetUiFontSize, _window, cx| {
+                theme::reset_ui_font_size(cx);
+                if action.persist {
+                    update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, _| {
+                        let _ = settings.ui_font_size.take();
+                    });
+                }
             }
         })
         .register_action({
             let fs = app_state.fs.clone();
-            move |_, _: &zed_actions::IncreaseBufferFontSize, _window, cx| {
-                update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
-                    let buffer_font_size = ThemeSettings::clamp_font_size(
-                        ThemeSettings::get_global(cx).buffer_font_size() + px(1.),
-                    );
-
-                    let _ = settings.buffer_font_size.insert(buffer_font_size.into());
+            move |_, action: &zed_actions::IncreaseBufferFontSize, _window, cx| {
+                theme::adjust_buffer_font_size(cx, |size| {
+                    *size += px(1.0);
                 });
+                if action.persist {
+                    update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
+                        let _ = settings
+                            .buffer_font_size
+                            .insert(theme::get_buffer_font_size(cx).0);
+                    });
+                }
             }
         })
         .register_action({
             let fs = app_state.fs.clone();
-            move |_, _: &zed_actions::DecreaseBufferFontSize, _window, cx| {
-                update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
-                    let buffer_font_size = ThemeSettings::clamp_font_size(
-                        ThemeSettings::get_global(cx).buffer_font_size() - px(1.),
-                    );
-                    let _ = settings.buffer_font_size.insert(buffer_font_size.into());
+            move |_, action: &zed_actions::DecreaseBufferFontSize, _window, cx| {
+                theme::adjust_buffer_font_size(cx, |size| {
+                    *size -= px(1.0);
                 });
+                if action.persist {
+                    update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, cx| {
+                        let _ = settings
+                            .buffer_font_size
+                            .insert(theme::get_buffer_font_size(cx).0);
+                    });
+                }
             }
         })
         .register_action({
             let fs = app_state.fs.clone();
-            move |_, _: &zed_actions::ResetBufferFontSize, _window, cx| {
-                update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, _| {
-                    let _ = settings.buffer_font_size.take();
-                });
+            move |_, action: &zed_actions::ResetBufferFontSize, _window, cx| {
+                theme::reset_buffer_font_size(cx);
+                if action.persist {
+                    update_settings_file::<ThemeSettings>(fs.clone(), cx, move |settings, _| {
+                        let _ = settings.buffer_font_size.take();
+                    });
+                }
             }
         })
         .register_action(install_cli)

crates/zed/src/zed/app_menus.rs 🔗

@@ -131,9 +131,18 @@ pub fn app_menus() -> Vec<Menu> {
         Menu {
             name: "View".into(),
             items: vec![
-                MenuItem::action("Zoom In", zed_actions::IncreaseBufferFontSize),
-                MenuItem::action("Zoom Out", zed_actions::DecreaseBufferFontSize),
-                MenuItem::action("Reset Zoom", zed_actions::ResetBufferFontSize),
+                MenuItem::action(
+                    "Zoom In",
+                    zed_actions::IncreaseBufferFontSize { persist: true },
+                ),
+                MenuItem::action(
+                    "Zoom Out",
+                    zed_actions::DecreaseBufferFontSize { persist: true },
+                ),
+                MenuItem::action(
+                    "Reset Zoom",
+                    zed_actions::ResetBufferFontSize { persist: true },
+                ),
                 MenuItem::separator(),
                 MenuItem::action("Toggle Left Dock", workspace::ToggleLeftDock),
                 MenuItem::action("Toggle Right Dock", workspace::ToggleRightDock),

crates/zed_actions/src/lib.rs 🔗

@@ -38,6 +38,48 @@ actions!(
         Extensions,
         OpenLicenses,
         OpenTelemetryLog,
+    ]
+);
+
+#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
+pub struct DecreaseBufferFontSize {
+    #[serde(default)]
+    pub persist: bool,
+}
+
+#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
+pub struct IncreaseBufferFontSize {
+    #[serde(default)]
+    pub persist: bool,
+}
+
+#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
+pub struct ResetBufferFontSize {
+    #[serde(default)]
+    pub persist: bool,
+}
+
+#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
+pub struct DecreaseUiFontSize {
+    #[serde(default)]
+    pub persist: bool,
+}
+
+#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
+pub struct IncreaseUiFontSize {
+    #[serde(default)]
+    pub persist: bool,
+}
+
+#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema)]
+pub struct ResetUiFontSize {
+    #[serde(default)]
+    pub persist: bool,
+}
+
+impl_actions!(
+    zed,
+    [
         DecreaseBufferFontSize,
         IncreaseBufferFontSize,
         ResetBufferFontSize,

crates/zeta/src/completion_diff_element.rs 🔗

@@ -69,7 +69,7 @@ impl CompletionDiffElement {
         let settings = ThemeSettings::get_global(cx).clone();
         let text_style = TextStyle {
             color: cx.theme().colors().editor_foreground,
-            font_size: settings.buffer_font_size().into(),
+            font_size: settings.buffer_font_size(cx).into(),
             font_family: settings.buffer_font.family,
             font_features: settings.buffer_font.features,
             font_fallbacks: settings.buffer_font.fallbacks,