text_view: Add to support custom code block style. (#1288)
And remove bg, padding for editor hover code blocks. <img width="589" height="214" alt="image" src="https://github.com/user-attachments/assets/55870f2f-e49e-4c2d-8899-9aa7edd17630" />
This commit is contained in:
parent
a6a14fd57b
commit
512f46aec8
5 changed files with 94 additions and 67 deletions
|
|
@ -11,13 +11,13 @@ pub(crate) use diagnostic_popover::*;
|
|||
pub(crate) use hover_popover::*;
|
||||
|
||||
use gpui::{
|
||||
div, rems, App, Div, ElementId, Entity, InteractiveElement as _, IntoElement, SharedString,
|
||||
Stateful, Styled as _, Window,
|
||||
div, px, rems, App, Div, ElementId, Entity, InteractiveElement as _, IntoElement, SharedString,
|
||||
Stateful, StyleRefinement, Styled as _, Window,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
text::{TextView, TextViewStyle},
|
||||
StyledExt as _,
|
||||
ActiveTheme, StyledExt as _,
|
||||
};
|
||||
|
||||
pub(crate) enum ContextMenu {
|
||||
|
|
@ -58,7 +58,13 @@ pub(super) fn render_markdown(
|
|||
1..=3 => rem_size * 1,
|
||||
4 => rem_size * 0.9,
|
||||
_ => rem_size * 0.8,
|
||||
}),
|
||||
})
|
||||
.code_block(
|
||||
StyleRefinement::default()
|
||||
.bg(cx.theme().transparent)
|
||||
.p_0()
|
||||
.text_size(px(11.)),
|
||||
),
|
||||
)
|
||||
.selectable()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
mod format;
|
||||
mod inline;
|
||||
mod node;
|
||||
mod style;
|
||||
mod text_view;
|
||||
mod utils;
|
||||
|
||||
use gpui::App;
|
||||
pub use style::*;
|
||||
pub use text_view::*;
|
||||
|
||||
pub(crate) fn init(cx: &mut App) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::{collections::HashMap, ops::Range};
|
|||
use gpui::{
|
||||
div, img, prelude::FluentBuilder as _, px, relative, rems, AnyElement, App, DefiniteLength,
|
||||
Div, ElementId, FontStyle, FontWeight, Half, HighlightStyle, InteractiveElement as _,
|
||||
IntoElement, Length, ObjectFit, ParentElement, Rems, SharedString, SharedUri,
|
||||
IntoElement, Length, ObjectFit, ParentElement, SharedString, SharedUri,
|
||||
StatefulInteractiveElement, Styled, StyledImage as _, Window,
|
||||
};
|
||||
use markdown::mdast;
|
||||
|
|
@ -14,7 +14,7 @@ use crate::{
|
|||
highlighter::SyntaxHighlighter,
|
||||
text::inline::{Inline, InlineState},
|
||||
tooltip::Tooltip,
|
||||
v_flex, ActiveTheme as _, Icon, IconName,
|
||||
v_flex, ActiveTheme as _, Icon, IconName, StyledExt,
|
||||
};
|
||||
|
||||
use super::{utils::list_item_prefix, TextViewStyle};
|
||||
|
|
@ -318,16 +318,19 @@ impl CodeBlock {
|
|||
text
|
||||
}
|
||||
|
||||
fn render(&self, mb: Rems, _: &mut Window, cx: &mut App) -> AnyElement {
|
||||
fn render(&self, node_cx: &NodeContext, _: &mut Window, cx: &mut App) -> AnyElement {
|
||||
let style = &node_cx.style;
|
||||
|
||||
div()
|
||||
.id("codeblock")
|
||||
.mb(mb)
|
||||
.mb(style.paragraph_gap)
|
||||
.p_3()
|
||||
.rounded(cx.theme().radius)
|
||||
.bg(cx.theme().accent)
|
||||
.font_family("Menlo, Monaco, Consolas, monospace")
|
||||
.text_size(rems(0.875))
|
||||
.relative()
|
||||
.refine_style(&style.code_block)
|
||||
.child(Inline::new(
|
||||
"code",
|
||||
self.state.clone(),
|
||||
|
|
@ -927,7 +930,7 @@ impl Node {
|
|||
items
|
||||
})
|
||||
.into_any_element(),
|
||||
Node::CodeBlock(code_block) => code_block.render(mb, window, cx),
|
||||
Node::CodeBlock(code_block) => code_block.render(node_cx, window, cx),
|
||||
Node::Table { .. } => Self::render_table(&self, node_cx, window, cx).into_any_element(),
|
||||
Node::Divider => div()
|
||||
.id("divider")
|
||||
|
|
|
|||
67
crates/ui/src/text/style.rs
Normal file
67
crates/ui/src/text/style.rs
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
use std::{rc::Rc, sync::Arc};
|
||||
|
||||
use gpui::{px, rems, Pixels, Rems, StyleRefinement};
|
||||
|
||||
use crate::highlighter::HighlightTheme;
|
||||
|
||||
/// TextViewStyle used to customize the style for [`TextView`].
|
||||
#[derive(Clone)]
|
||||
pub struct TextViewStyle {
|
||||
/// Gap of each paragraphs, default is 1 rem.
|
||||
pub paragraph_gap: Rems,
|
||||
/// Base font size for headings, default is 14px.
|
||||
pub heading_base_font_size: Pixels,
|
||||
/// Function to calculate heading font size based on heading level (1-6).
|
||||
///
|
||||
/// The first parameter is the heading level (1-6), the second parameter is the base font size.
|
||||
/// The second parameter is the base font size.
|
||||
pub heading_font_size: Option<Rc<dyn Fn(u8, Pixels) -> Pixels + 'static>>,
|
||||
/// Highlight theme for code blocks. Default: [`HighlightTheme::default_light()`]
|
||||
pub highlight_theme: Arc<HighlightTheme>,
|
||||
/// The style refinement for code blocks.
|
||||
pub code_block: StyleRefinement,
|
||||
pub is_dark: bool,
|
||||
}
|
||||
|
||||
impl PartialEq for TextViewStyle {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.paragraph_gap == other.paragraph_gap
|
||||
&& self.heading_base_font_size == other.heading_base_font_size
|
||||
&& self.highlight_theme == other.highlight_theme
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for TextViewStyle {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
paragraph_gap: rems(1.),
|
||||
heading_base_font_size: px(14.),
|
||||
heading_font_size: None,
|
||||
highlight_theme: HighlightTheme::default_light().clone(),
|
||||
code_block: StyleRefinement::default(),
|
||||
is_dark: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TextViewStyle {
|
||||
/// Set paragraph gap, default is 1 rem.
|
||||
pub fn paragraph_gap(mut self, gap: Rems) -> Self {
|
||||
self.paragraph_gap = gap;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn heading_font_size<F>(mut self, f: F) -> Self
|
||||
where
|
||||
F: Fn(u8, Pixels) -> Pixels + 'static,
|
||||
{
|
||||
self.heading_font_size = Some(Rc::new(f));
|
||||
self
|
||||
}
|
||||
|
||||
/// Set style for code blocks.
|
||||
pub fn code_block(mut self, style: StyleRefinement) -> Self {
|
||||
self.code_block = style;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +1,20 @@
|
|||
use std::{rc::Rc, sync::Arc, time::Instant};
|
||||
use std::{rc::Rc, time::Instant};
|
||||
|
||||
use gpui::{
|
||||
div, px, rems, AnyElement, App, Bounds, ClipboardItem, Element, ElementId, Entity, FocusHandle,
|
||||
div, AnyElement, App, Bounds, ClipboardItem, Element, ElementId, Entity, FocusHandle,
|
||||
GlobalElementId, InspectorElementId, InteractiveElement, IntoElement, KeyBinding, LayoutId,
|
||||
MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, Point, Rems, RenderOnce,
|
||||
MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, Point, RenderOnce,
|
||||
SharedString, Size, Window,
|
||||
};
|
||||
|
||||
use super::format::{html::HtmlElement, markdown::MarkdownElement};
|
||||
use crate::{
|
||||
global_state::GlobalState,
|
||||
highlighter::HighlightTheme,
|
||||
input::{self},
|
||||
text::node::{self, NodeContext},
|
||||
text::{
|
||||
node::{self, NodeContext},
|
||||
TextViewStyle,
|
||||
},
|
||||
};
|
||||
|
||||
const CONTEXT: &'static str = "TextView";
|
||||
|
|
@ -270,59 +272,6 @@ impl RenderOnce for Text {
|
|||
}
|
||||
}
|
||||
|
||||
/// TextViewStyle used to customize the style for [`TextView`].
|
||||
#[derive(Clone)]
|
||||
pub struct TextViewStyle {
|
||||
/// Gap of each paragraphs, default is 1 rem.
|
||||
pub paragraph_gap: Rems,
|
||||
/// Base font size for headings, default is 14px.
|
||||
pub heading_base_font_size: Pixels,
|
||||
/// Function to calculate heading font size based on heading level (1-6).
|
||||
///
|
||||
/// The first parameter is the heading level (1-6), the second parameter is the base font size.
|
||||
/// The second parameter is the base font size.
|
||||
pub heading_font_size: Option<Rc<dyn Fn(u8, Pixels) -> Pixels + 'static>>,
|
||||
/// Highlight theme for code blocks. Default: [`HighlightTheme::default_light()`]
|
||||
pub highlight_theme: Arc<HighlightTheme>,
|
||||
pub is_dark: bool,
|
||||
}
|
||||
|
||||
impl PartialEq for TextViewStyle {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.paragraph_gap == other.paragraph_gap
|
||||
&& self.heading_base_font_size == other.heading_base_font_size
|
||||
&& self.highlight_theme == other.highlight_theme
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for TextViewStyle {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
paragraph_gap: rems(1.),
|
||||
heading_base_font_size: px(14.),
|
||||
heading_font_size: None,
|
||||
highlight_theme: HighlightTheme::default_light().clone(),
|
||||
is_dark: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TextViewStyle {
|
||||
/// Set paragraph gap, default is 1 rem.
|
||||
pub fn paragraph_gap(mut self, gap: Rems) -> Self {
|
||||
self.paragraph_gap = gap;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn heading_font_size<F>(mut self, f: F) -> Self
|
||||
where
|
||||
F: Fn(u8, Pixels) -> Pixels + 'static,
|
||||
{
|
||||
self.heading_font_size = Some(Rc::new(f));
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl TextView {
|
||||
/// Create a new markdown text view.
|
||||
pub fn markdown(
|
||||
|
|
|
|||
Loading…
Reference in a new issue