markdown_preview: Add font size settings and actions (#55489)
Add support for scaling the Markdown preview's body text and headings with `cmd-=` / `cmd--` / `cmd-0`. Previously these shortcuts only resized code blocks because the preview's body used `ui_font_size` and headings used a rem-based scale anchored to it, while the keybindings only mutated `BufferFontSize`. The preview's scroll subtree is now wrapped in `WithRemSize(buffer_font_size)`, so `1rem` resolves to the buffer font size inside the preview. Body text, headings (`text_3xl`/`text_2xl`/...), and rem-based spacing all scale together. The outer focus root and scrollbar remain at the UI font size. Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Closes #55374 Release Notes: - Added `markdown_preview_font_size` setting and actions to scale Markdown preview font size separately from the editor. --------- Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
This commit is contained in:
1 parent
fea22b3934
commit
4306847359
9 files changed
+349
-47
No files matched your search
@@ -73,6 +73,12 @@
|
||||
"agent_buffer_font_size": 12,
|
||||
// The default font size for the commit editor in the git panel and commit modal.
|
||||
"git_commit_buffer_font_size": 12,
|
||||
// The default font size for the markdown preview. Falls back to the editor font size if unset.
|
||||
"markdown_preview_font_size": null,
|
||||
// The font family for the markdown preview. Falls back to the UI font family if unset.
|
||||
"markdown_preview_font_family": null,
|
||||
// The font family for code blocks in the markdown preview. Falls back to the editor font family if unset.
|
||||
"markdown_preview_code_font_family": null,
|
||||
// How much to fade out unused code.
|
||||
"unnecessary_code_fade": 0.3,
|
||||
// Active pane styling settings.
|
||||
|
||||
@@ -175,10 +175,14 @@ impl MarkdownStyle {
|
||||
theme_settings.agent_buffer_font_size(cx),
|
||||
theme_settings.agent_ui_font_size(cx),
|
||||
),
|
||||
MarkdownFont::Editor | MarkdownFont::Preview => (
|
||||
MarkdownFont::Editor => (
|
||||
theme_settings.buffer_font_size(cx),
|
||||
theme_settings.ui_font_size(cx),
|
||||
),
|
||||
MarkdownFont::Preview => (
|
||||
theme_settings.markdown_preview_font_size(cx),
|
||||
theme_settings.ui_font_size(cx),
|
||||
),
|
||||
};
|
||||
|
||||
let body_font_family = if is_preview {
|
||||
@@ -199,7 +203,11 @@ impl MarkdownStyle {
|
||||
font_family: Some(body_font_family),
|
||||
font_fallbacks: theme_settings.ui_font.fallbacks.clone(),
|
||||
font_features: Some(theme_settings.ui_font.features.clone()),
|
||||
font_size: Some(ui_font_size.into()),
|
||||
font_size: Some(if is_preview {
|
||||
rems(1.0).into()
|
||||
} else {
|
||||
ui_font_size.into()
|
||||
}),
|
||||
line_height: Some(line_height.into()),
|
||||
color: Some(colors.text),
|
||||
..Default::default()
|
||||
@@ -306,14 +314,14 @@ impl MarkdownStyle {
|
||||
};
|
||||
|
||||
if is_preview {
|
||||
style.with_preview_overrides(ui_font_size, colors)
|
||||
style.with_preview_overrides(colors)
|
||||
} else {
|
||||
style
|
||||
}
|
||||
}
|
||||
|
||||
fn with_preview_overrides(mut self, ui_font_size: Pixels, colors: &theme::ThemeColors) -> Self {
|
||||
let body_font_size = ui_font_size * 0.92;
|
||||
fn with_preview_overrides(mut self, colors: &theme::ThemeColors) -> Self {
|
||||
let body_font_size = rems(0.92);
|
||||
self.base_text_style.font_size = body_font_size.into();
|
||||
self.container_style.text.font_size = Some(body_font_size.into());
|
||||
|
||||
@@ -3966,7 +3974,7 @@ impl RenderedText {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use gpui::{RenderImage, TestAppContext, size};
|
||||
use gpui::{RenderImage, TestAppContext, UpdateGlobal, size};
|
||||
use language::{Language, LanguageConfig, LanguageMatcher};
|
||||
use std::sync::{
|
||||
Arc,
|
||||
@@ -5168,6 +5176,28 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn test_preview_body_font_size_is_rem_based(cx: &mut TestAppContext) {
|
||||
ensure_theme_initialized(cx);
|
||||
let (_, cx) = cx.add_window_view(|_, _| TestWindow);
|
||||
cx.update(|window, cx| {
|
||||
let style = MarkdownStyle::themed(MarkdownFont::Preview, window, cx);
|
||||
assert!(
|
||||
matches!(style.base_text_style.font_size, AbsoluteLength::Rems(_)),
|
||||
"preview body font size must be rem-based, got {:?}",
|
||||
style.base_text_style.font_size
|
||||
);
|
||||
assert!(
|
||||
matches!(
|
||||
style.container_style.text.font_size,
|
||||
Some(AbsoluteLength::Rems(_))
|
||||
),
|
||||
"preview container font size must be rem-based, got {:?}",
|
||||
style.container_style.text.font_size
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn assert_mappings(rendered: &RenderedText, expected: Vec<Vec<(usize, usize)>>) {
|
||||
assert_eq!(rendered.lines.len(), expected.len(), "line count mismatch");
|
||||
@@ -5276,4 +5306,70 @@ mod tests {
|
||||
"H3 line height ({h3_line_height:?}) should be greater than body text ({body_line_height:?})"
|
||||
);
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn test_editor_zoom_does_not_affect_markdown_preview(cx: &mut TestAppContext) {
|
||||
ensure_theme_initialized(cx);
|
||||
|
||||
cx.update(|cx| {
|
||||
settings::SettingsStore::update_global(cx, |store, cx| {
|
||||
store.update_user_settings(cx, |settings| {
|
||||
settings.theme.buffer_font_size = Some(16.0.into());
|
||||
settings.theme.markdown_preview_font_size = None;
|
||||
});
|
||||
});
|
||||
});
|
||||
cx.run_until_parked();
|
||||
|
||||
cx.update(|cx| {
|
||||
let before = ThemeSettings::get_global(cx).markdown_preview_font_size(cx);
|
||||
assert_eq!(before, px(16.0));
|
||||
|
||||
theme_settings::increase_buffer_font_size(cx);
|
||||
theme_settings::increase_buffer_font_size(cx);
|
||||
theme_settings::increase_buffer_font_size(cx);
|
||||
|
||||
assert_eq!(ThemeSettings::get_global(cx).buffer_font_size(cx), px(19.0));
|
||||
assert_eq!(
|
||||
ThemeSettings::get_global(cx).markdown_preview_font_size(cx),
|
||||
before
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
fn test_markdown_preview_follows_buffer_font_size_setting_when_unset(cx: &mut TestAppContext) {
|
||||
ensure_theme_initialized(cx);
|
||||
|
||||
cx.update(|cx| {
|
||||
settings::SettingsStore::update_global(cx, |store, cx| {
|
||||
store.update_user_settings(cx, |settings| {
|
||||
settings.theme.buffer_font_size = Some(20.0.into());
|
||||
settings.theme.markdown_preview_font_size = None;
|
||||
});
|
||||
});
|
||||
});
|
||||
cx.run_until_parked();
|
||||
cx.update(|cx| {
|
||||
assert_eq!(
|
||||
ThemeSettings::get_global(cx).markdown_preview_font_size(cx),
|
||||
px(20.0)
|
||||
);
|
||||
});
|
||||
|
||||
cx.update(|cx| {
|
||||
settings::SettingsStore::update_global(cx, |store, cx| {
|
||||
store.update_user_settings(cx, |settings| {
|
||||
settings.theme.buffer_font_size = Some(24.0.into());
|
||||
});
|
||||
});
|
||||
});
|
||||
cx.run_until_parked();
|
||||
cx.update(|cx| {
|
||||
assert_eq!(
|
||||
ThemeSettings::get_global(cx).markdown_preview_font_size(cx),
|
||||
px(24.0)
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ use editor::{Editor, EditorEvent, MultiBufferOffset, SelectionEffects};
|
||||
use gpui::{
|
||||
App, ClipboardItem, Context, Entity, EventEmitter, FocusHandle, Focusable, ImageSource,
|
||||
InteractiveElement, IntoElement, IsZero, Pixels, Render, Resource, RetainAllImageCache,
|
||||
ScrollHandle, SharedString, SharedUri, Subscription, Task, WeakEntity, Window, point,
|
||||
ScrollHandle, SharedString, SharedUri, Subscription, Task, WeakEntity, Window, point, px,
|
||||
};
|
||||
use language::LanguageRegistry;
|
||||
use markdown::{
|
||||
@@ -21,9 +21,10 @@ use markdown::{
|
||||
};
|
||||
use project::search::SearchQuery;
|
||||
use project::{Project, ProjectPath};
|
||||
use settings::{SeedQuerySetting, Settings};
|
||||
use settings::{SeedQuerySetting, Settings, update_settings_file};
|
||||
use theme::{SystemAppearance, Theme, ThemeRegistry};
|
||||
use theme_settings::ThemeSettings;
|
||||
use ui::utils::WithRemSize;
|
||||
use ui::{ContextMenu, WithScrollbar, prelude::*, right_click_menu};
|
||||
use util::markdown::split_local_url_fragment;
|
||||
use workspace::item::{Item, ItemBufferKind, ItemHandle, SaveOptions, SerializableItem};
|
||||
@@ -31,6 +32,7 @@ use workspace::searchable::{
|
||||
Direction, SearchEvent, SearchOptions, SearchToken, SearchableItem, SearchableItemHandle,
|
||||
};
|
||||
use workspace::{ItemId, Pane, Workspace, WorkspaceId, delete_unloaded_items};
|
||||
use zed_actions::{DecreaseBufferFontSize, IncreaseBufferFontSize, ResetBufferFontSize};
|
||||
|
||||
use crate::markdown_preview_settings::MarkdownPreviewSettings;
|
||||
use crate::{
|
||||
@@ -589,7 +591,64 @@ impl MarkdownPreviewView {
|
||||
|
||||
fn line_scroll_amount(&self, cx: &App) -> Pixels {
|
||||
let settings = ThemeSettings::get_global(cx);
|
||||
settings.buffer_font_size(cx) * settings.buffer_line_height.value()
|
||||
settings.markdown_preview_font_size(cx) * settings.buffer_line_height.value()
|
||||
}
|
||||
|
||||
fn increase_font_size(
|
||||
&mut self,
|
||||
action: &IncreaseBufferFontSize,
|
||||
_: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.adjust_font_size(action.persist, px(1.0), cx);
|
||||
}
|
||||
|
||||
fn decrease_font_size(
|
||||
&mut self,
|
||||
action: &DecreaseBufferFontSize,
|
||||
_: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
self.adjust_font_size(action.persist, px(-1.0), cx);
|
||||
}
|
||||
|
||||
fn adjust_font_size(&mut self, persist: bool, delta: Pixels, cx: &mut Context<Self>) {
|
||||
if persist {
|
||||
let Ok(fs) = self
|
||||
.workspace
|
||||
.read_with(cx, |workspace, _| workspace.app_state().fs.clone())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
update_settings_file(fs, cx, move |settings, cx| {
|
||||
let size = ThemeSettings::get_global(cx).markdown_preview_font_size(cx) + delta;
|
||||
settings.theme.markdown_preview_font_size =
|
||||
Some(f32::from(theme_settings::clamp_font_size(size)).into());
|
||||
});
|
||||
} else {
|
||||
theme_settings::adjust_markdown_preview_font_size(cx, |size| size + delta);
|
||||
}
|
||||
}
|
||||
|
||||
fn reset_font_size(
|
||||
&mut self,
|
||||
action: &ResetBufferFontSize,
|
||||
_: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) {
|
||||
if action.persist {
|
||||
let Ok(fs) = self
|
||||
.workspace
|
||||
.read_with(cx, |workspace, _| workspace.app_state().fs.clone())
|
||||
else {
|
||||
return;
|
||||
};
|
||||
update_settings_file(fs, cx, move |settings, _| {
|
||||
settings.theme.markdown_preview_font_size = None;
|
||||
});
|
||||
} else {
|
||||
theme_settings::reset_markdown_preview_font_size(cx);
|
||||
}
|
||||
}
|
||||
|
||||
fn scroll_by_amount(&self, distance: Pixels) {
|
||||
@@ -1127,6 +1186,7 @@ impl Render for MarkdownPreviewView {
|
||||
.as_ref()
|
||||
.map(|theme| theme.colors().editor_background)
|
||||
.unwrap_or_else(|| cx.theme().colors().editor_background);
|
||||
let preview_font_size = ThemeSettings::get_global(cx).markdown_preview_font_size(cx);
|
||||
div()
|
||||
.image_cache(self.image_cache.clone())
|
||||
.id("MarkdownPreview")
|
||||
@@ -1140,44 +1200,51 @@ impl Render for MarkdownPreviewView {
|
||||
.on_action(cx.listener(MarkdownPreviewView::scroll_down_by_item))
|
||||
.on_action(cx.listener(MarkdownPreviewView::scroll_to_top))
|
||||
.on_action(cx.listener(MarkdownPreviewView::scroll_to_bottom))
|
||||
.on_action(cx.listener(MarkdownPreviewView::increase_font_size))
|
||||
.on_action(cx.listener(MarkdownPreviewView::decrease_font_size))
|
||||
.on_action(cx.listener(MarkdownPreviewView::reset_font_size))
|
||||
.w_full()
|
||||
.flex_1()
|
||||
.min_h_0()
|
||||
.bg(bg_color)
|
||||
.child(
|
||||
div()
|
||||
.id("markdown-preview-scroll-container")
|
||||
.size_full()
|
||||
.overflow_y_scroll()
|
||||
.track_scroll(&self.scroll_handle)
|
||||
.p_4()
|
||||
.child({
|
||||
let markdown_element =
|
||||
self.render_markdown_element(&preview_theme, window, cx);
|
||||
let markdown = self.markdown.clone();
|
||||
let max_width = MarkdownPreviewSettings::get_global(cx).max_width;
|
||||
let content = right_click_menu("markdown-preview-context-menu")
|
||||
.trigger(move |_, _, _| markdown_element)
|
||||
.menu(move |window, cx| {
|
||||
let focus = window.focused(cx);
|
||||
let context_menu_link =
|
||||
markdown.read(cx).context_menu_link().cloned();
|
||||
ContextMenu::build(window, cx, move |menu, _, _cx| {
|
||||
menu.when_some(focus, |menu, focus| menu.context(focus))
|
||||
.when_some(context_menu_link, |menu, url| {
|
||||
menu.entry("Copy Link", None, move |_, cx| {
|
||||
cx.write_to_clipboard(ClipboardItem::new_string(
|
||||
url.to_string(),
|
||||
));
|
||||
WithRemSize::new(preview_font_size).size_full().child(
|
||||
div()
|
||||
.id("markdown-preview-scroll-container")
|
||||
.size_full()
|
||||
.overflow_y_scroll()
|
||||
.track_scroll(&self.scroll_handle)
|
||||
.p_4()
|
||||
.child({
|
||||
let markdown_element =
|
||||
self.render_markdown_element(&preview_theme, window, cx);
|
||||
let markdown = self.markdown.clone();
|
||||
let max_width = MarkdownPreviewSettings::get_global(cx).max_width;
|
||||
let content = right_click_menu("markdown-preview-context-menu")
|
||||
.trigger(move |_, _, _| markdown_element)
|
||||
.menu(move |window, cx| {
|
||||
let focus = window.focused(cx);
|
||||
let context_menu_link =
|
||||
markdown.read(cx).context_menu_link().cloned();
|
||||
ContextMenu::build(window, cx, move |menu, _, _cx| {
|
||||
menu.when_some(focus, |menu, focus| menu.context(focus))
|
||||
.when_some(context_menu_link, |menu, url| {
|
||||
menu.entry("Copy Link", None, move |_, cx| {
|
||||
cx.write_to_clipboard(
|
||||
ClipboardItem::new_string(url.to_string()),
|
||||
);
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
||||
div()
|
||||
.w_full()
|
||||
.when_some(max_width, |this, max_width| {
|
||||
this.max_w(max_width).mx_auto()
|
||||
})
|
||||
});
|
||||
div()
|
||||
.w_full()
|
||||
.when_some(max_width, |this, max_width| this.max_w(max_width).mx_auto())
|
||||
.child(content)
|
||||
}),
|
||||
.child(content)
|
||||
}),
|
||||
),
|
||||
)
|
||||
.vertical_scrollbar_for(&self.scroll_handle, window, cx)
|
||||
}
|
||||
|
||||
@@ -982,6 +982,7 @@ impl VsCodeSettings {
|
||||
git_commit_buffer_font_size: None,
|
||||
markdown_preview_font_family: None,
|
||||
markdown_preview_code_font_family: None,
|
||||
markdown_preview_font_size: None,
|
||||
markdown_preview_theme: None,
|
||||
theme: None,
|
||||
icon_theme: None,
|
||||
|
||||
@@ -156,6 +156,9 @@ pub struct ThemeSettingsContent {
|
||||
/// The name of a font to use for code (code blocks and inline code) in the
|
||||
/// markdown preview. Falls back to the buffer font if unset.
|
||||
pub markdown_preview_code_font_family: Option<FontFamilyName>,
|
||||
/// The font size to use for rendering in the markdown preview.
|
||||
/// Falls back to the buffer font size if unset.
|
||||
pub markdown_preview_font_size: Option<FontSize>,
|
||||
/// The theme to use for the markdown preview.
|
||||
/// Falls back to the main editor theme if unset.
|
||||
pub markdown_preview_theme: Option<ThemeSelection>,
|
||||
|
||||
@@ -1161,6 +1161,67 @@ fn appearance_page() -> SettingsPage {
|
||||
]
|
||||
}
|
||||
|
||||
fn markdown_preview_font_section() -> [SettingsPageItem; 4] {
|
||||
[
|
||||
SettingsPageItem::SectionHeader("Markdown Preview Font"),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Font Family",
|
||||
description: "Font family for the markdown preview. Falls back to the UI font family.",
|
||||
field: Box::new(SettingField {
|
||||
organization_override: None,
|
||||
json_path: Some("markdown_preview_font_family"),
|
||||
pick: |settings_content| {
|
||||
settings_content.theme.markdown_preview_font_family.as_ref()
|
||||
},
|
||||
write: |settings_content, value, _| {
|
||||
settings_content.theme.markdown_preview_font_family = value;
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
files: USER,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Code Font Family",
|
||||
description: "Font family for code blocks in the markdown preview. Falls back to the editor font family.",
|
||||
field: Box::new(SettingField {
|
||||
organization_override: None,
|
||||
json_path: Some("markdown_preview_code_font_family"),
|
||||
pick: |settings_content| {
|
||||
settings_content
|
||||
.theme
|
||||
.markdown_preview_code_font_family
|
||||
.as_ref()
|
||||
},
|
||||
write: |settings_content, value, _| {
|
||||
settings_content.theme.markdown_preview_code_font_family = value;
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
files: USER,
|
||||
}),
|
||||
SettingsPageItem::SettingItem(SettingItem {
|
||||
title: "Font Size",
|
||||
description: "Font size for the markdown preview. Falls back to the editor font size.",
|
||||
field: Box::new(SettingField {
|
||||
organization_override: None,
|
||||
json_path: Some("markdown_preview_font_size"),
|
||||
pick: |settings_content| {
|
||||
settings_content
|
||||
.theme
|
||||
.markdown_preview_font_size
|
||||
.as_ref()
|
||||
.or(settings_content.theme.buffer_font_size.as_ref())
|
||||
},
|
||||
write: |settings_content, value, _| {
|
||||
settings_content.theme.markdown_preview_font_size = value;
|
||||
},
|
||||
}),
|
||||
metadata: None,
|
||||
files: USER,
|
||||
}),
|
||||
]
|
||||
}
|
||||
|
||||
fn text_rendering_section() -> [SettingsPageItem; 2] {
|
||||
[
|
||||
SettingsPageItem::SectionHeader("Text Rendering"),
|
||||
@@ -1389,6 +1450,7 @@ fn appearance_page() -> SettingsPage {
|
||||
buffer_font_section(),
|
||||
ui_font_section(),
|
||||
agent_panel_font_section(),
|
||||
markdown_preview_font_section(),
|
||||
text_rendering_section(),
|
||||
cursor_section(),
|
||||
highlighting_section(),
|
||||
|
||||
@@ -63,6 +63,9 @@ pub struct ThemeSettings {
|
||||
/// The font family to use for code in the markdown preview.
|
||||
/// Falls back to the buffer font family if unset.
|
||||
markdown_preview_code_font_family: Option<SharedString>,
|
||||
/// The font size to use for rendering in the markdown preview.
|
||||
/// Falls back to the buffer font size if unset.
|
||||
markdown_preview_font_size: Option<Pixels>,
|
||||
/// The theme to use for the markdown preview.
|
||||
/// Falls back to the main editor theme if unset.
|
||||
pub markdown_preview_theme: Option<ThemeSelection>,
|
||||
@@ -124,6 +127,12 @@ pub struct GitCommitBufferFontSize(Pixels);
|
||||
|
||||
impl Global for GitCommitBufferFontSize {}
|
||||
|
||||
/// In-memory override for the markdown preview font size.
|
||||
#[derive(Default)]
|
||||
pub struct MarkdownPreviewFontSize(Pixels);
|
||||
|
||||
impl Global for MarkdownPreviewFontSize {}
|
||||
|
||||
/// Represents the selection of a theme, which can be either static or dynamic.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
|
||||
#[serde(untagged)]
|
||||
@@ -440,6 +449,18 @@ impl ThemeSettings {
|
||||
.unwrap_or(&self.buffer_font.family)
|
||||
}
|
||||
|
||||
/// Returns the markdown preview font size.
|
||||
///
|
||||
/// Note: the fallback deliberately uses `self.buffer_font_size` instead of `buffer_font_size(cx)`,
|
||||
/// so that temporary editor zoom does not also resize the markdown preview.
|
||||
pub fn markdown_preview_font_size(&self, cx: &App) -> Pixels {
|
||||
cx.try_global::<MarkdownPreviewFontSize>()
|
||||
.map(|size| size.0)
|
||||
.or(self.markdown_preview_font_size)
|
||||
.map(clamp_font_size)
|
||||
.unwrap_or_else(|| clamp_font_size(self.buffer_font_size))
|
||||
}
|
||||
|
||||
/// Returns the buffer font size, read from the settings.
|
||||
///
|
||||
/// The real buffer font size is stored in-memory, to support temporary font size changes.
|
||||
@@ -476,6 +497,14 @@ impl ThemeSettings {
|
||||
self.git_commit_buffer_font_size
|
||||
}
|
||||
|
||||
/// Returns the markdown preview font size, read from the settings.
|
||||
///
|
||||
/// The real markdown preview font size is stored in-memory, to support temporary
|
||||
/// font size changes. Use [`Self::markdown_preview_font_size`] to get the real font size.
|
||||
pub fn markdown_preview_font_size_settings(&self) -> Option<Pixels> {
|
||||
self.markdown_preview_font_size
|
||||
}
|
||||
|
||||
/// Returns the buffer's line height.
|
||||
pub fn line_height(&self) -> f32 {
|
||||
f32::max(self.buffer_line_height.value(), MIN_LINE_HEIGHT)
|
||||
@@ -643,6 +672,24 @@ pub fn reset_git_commit_buffer_font_size(cx: &mut App) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the adjusted font size of the markdown preview.
|
||||
pub fn adjust_markdown_preview_font_size(cx: &mut App, f: impl FnOnce(Pixels) -> Pixels) {
|
||||
let markdown_preview_font_size = ThemeSettings::get_global(cx).markdown_preview_font_size(cx);
|
||||
let adjusted_size = cx
|
||||
.try_global::<MarkdownPreviewFontSize>()
|
||||
.map_or(markdown_preview_font_size, |adjusted_size| adjusted_size.0);
|
||||
cx.set_global(MarkdownPreviewFontSize(clamp_font_size(f(adjusted_size))));
|
||||
cx.refresh_windows();
|
||||
}
|
||||
|
||||
/// Resets the markdown preview font size to the default value.
|
||||
pub fn reset_markdown_preview_font_size(cx: &mut App) {
|
||||
if cx.has_global::<MarkdownPreviewFontSize>() {
|
||||
cx.remove_global::<MarkdownPreviewFontSize>();
|
||||
cx.refresh_windows();
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensures font size is within the valid range.
|
||||
pub fn clamp_font_size(size: Pixels) -> Pixels {
|
||||
size.clamp(MIN_FONT_SIZE, MAX_FONT_SIZE)
|
||||
@@ -701,6 +748,7 @@ impl settings::Settings for ThemeSettings {
|
||||
.markdown_preview_code_font_family
|
||||
.as_ref()
|
||||
.map(|f| f.0.clone().into()),
|
||||
markdown_preview_font_size: content.markdown_preview_font_size.map(|s| s.into_gpui()),
|
||||
markdown_preview_theme: content
|
||||
.markdown_preview_theme
|
||||
.clone()
|
||||
|
||||
@@ -29,13 +29,14 @@ pub use crate::schema::{
|
||||
use crate::settings::adjust_buffer_font_size;
|
||||
pub use crate::settings::{
|
||||
AgentBufferFontSize, AgentUiFontSize, BufferLineHeight, FontFamilyName,
|
||||
GitCommitBufferFontSize, IconThemeName, IconThemeSelection, ThemeAppearanceMode, ThemeName,
|
||||
ThemeSelection, ThemeSettings, adjust_agent_buffer_font_size, adjust_agent_ui_font_size,
|
||||
adjust_git_commit_buffer_font_size, adjust_ui_font_size, adjusted_font_size,
|
||||
appearance_to_mode, clamp_font_size, default_theme, observe_buffer_font_size_adjustment,
|
||||
GitCommitBufferFontSize, IconThemeName, IconThemeSelection, MarkdownPreviewFontSize,
|
||||
ThemeAppearanceMode, ThemeName, ThemeSelection, ThemeSettings, adjust_agent_buffer_font_size,
|
||||
adjust_agent_ui_font_size, adjust_git_commit_buffer_font_size,
|
||||
adjust_markdown_preview_font_size, adjust_ui_font_size, adjusted_font_size, appearance_to_mode,
|
||||
clamp_font_size, default_theme, observe_buffer_font_size_adjustment,
|
||||
reset_agent_buffer_font_size, reset_agent_ui_font_size, reset_buffer_font_size,
|
||||
reset_git_commit_buffer_font_size, reset_ui_font_size, set_icon_theme, set_mode, set_theme,
|
||||
setup_ui_font,
|
||||
reset_git_commit_buffer_font_size, reset_markdown_preview_font_size, reset_ui_font_size,
|
||||
set_icon_theme, set_mode, set_theme, setup_ui_font,
|
||||
};
|
||||
pub use theme::UiDensity;
|
||||
|
||||
@@ -91,6 +92,8 @@ pub fn init(themes_to_load: LoadThemes, cx: &mut App) {
|
||||
let mut prev_agent_buffer_font_size_settings = settings.agent_buffer_font_size_settings();
|
||||
let mut prev_git_commit_buffer_font_size_settings =
|
||||
settings.git_commit_buffer_font_size_settings();
|
||||
let mut prev_markdown_preview_font_size_settings =
|
||||
settings.markdown_preview_font_size_settings();
|
||||
let mut prev_theme_name = settings.theme.name(SystemAppearance::global(cx).0);
|
||||
let mut prev_icon_theme_name = settings.icon_theme.name(SystemAppearance::global(cx).0);
|
||||
let mut prev_theme_overrides = (
|
||||
@@ -106,6 +109,7 @@ pub fn init(themes_to_load: LoadThemes, cx: &mut App) {
|
||||
let agent_ui_font_size_settings = settings.agent_ui_font_size_settings();
|
||||
let agent_buffer_font_size_settings = settings.agent_buffer_font_size_settings();
|
||||
let git_commit_buffer_font_size_settings = settings.git_commit_buffer_font_size_settings();
|
||||
let markdown_preview_font_size_settings = settings.markdown_preview_font_size_settings();
|
||||
let theme_name = settings.theme.name(SystemAppearance::global(cx).0);
|
||||
let icon_theme_name = settings.icon_theme.name(SystemAppearance::global(cx).0);
|
||||
let theme_overrides = (
|
||||
@@ -138,6 +142,11 @@ pub fn init(themes_to_load: LoadThemes, cx: &mut App) {
|
||||
reset_git_commit_buffer_font_size(cx);
|
||||
}
|
||||
|
||||
if markdown_preview_font_size_settings != prev_markdown_preview_font_size_settings {
|
||||
prev_markdown_preview_font_size_settings = markdown_preview_font_size_settings;
|
||||
reset_markdown_preview_font_size(cx);
|
||||
}
|
||||
|
||||
if theme_name != prev_theme_name || theme_overrides != prev_theme_overrides {
|
||||
prev_theme_name = theme_name;
|
||||
prev_theme_overrides = theme_overrides;
|
||||
|
||||
@@ -71,7 +71,17 @@ If you would like to use distinct themes for light mode/dark mode that can be se
|
||||
"agent_ui_font_size": 15,
|
||||
// Controls the font size for the agent panel's message editor, user message,
|
||||
// and any other snippet of code.
|
||||
"agent_buffer_font_size": 12
|
||||
"agent_buffer_font_size": 12,
|
||||
|
||||
// Controls the font size for the markdown preview.
|
||||
// If not specified, it falls back to the editor font size.
|
||||
"markdown_preview_font_size": null,
|
||||
// Controls the font family for the markdown preview.
|
||||
// If not specified, it falls back to the UI font family.
|
||||
"markdown_preview_font_family": null,
|
||||
// Controls the font family for code blocks in the markdown preview.
|
||||
// If not specified, it falls back to the editor font family.
|
||||
"markdown_preview_code_font_family": null
|
||||
```
|
||||
|
||||
### Font ligatures
|
||||
|
||||
Reference in new issue
Block a user