1use assets::Assets;
2use gpui::{Application, Entity, KeyBinding, StyleRefinement, WindowOptions, prelude::*, rgb};
3use language::{LanguageRegistry, language_settings::AllLanguageSettings};
4use markdown::{Markdown, MarkdownElement, MarkdownStyle};
5use node_runtime::NodeRuntime;
6use settings::SettingsStore;
7use std::sync::Arc;
8use theme::LoadThemes;
9use ui::prelude::*;
10use ui::{App, Window, div};
11
12const MARKDOWN_EXAMPLE: &str = r#"
13# Markdown Example Document
14
15## Headings
16Headings are created by adding one or more `#` symbols before your heading text. The number of `#` you use will determine the size of the heading.
17
18```
19function a(b: T) {
20
21}
22```
23
24Remember, markdown processors may have slight differences and extensions, so always refer to the specific documentation or guides relevant to your platform or editor for the best practices and additional features.
25"#;
26
27pub fn main() {
28 env_logger::init();
29 Application::new().with_assets(Assets).run(|cx| {
30 let store = SettingsStore::test(cx);
31 cx.set_global(store);
32 language::init(cx);
33 SettingsStore::update(cx, |store, cx| {
34 store.update_user_settings::<AllLanguageSettings>(cx, |_| {});
35 });
36 cx.bind_keys([KeyBinding::new("cmd-c", markdown::Copy, None)]);
37
38 let node_runtime = NodeRuntime::unavailable();
39 theme::init(LoadThemes::JustBase, cx);
40
41 let language_registry = LanguageRegistry::new(cx.background_executor().clone());
42 language_registry.set_theme(cx.theme().clone());
43 let language_registry = Arc::new(language_registry);
44 languages::init(language_registry.clone(), node_runtime, cx);
45 Assets.load_fonts(cx).unwrap();
46
47 cx.activate(true);
48 cx.open_window(WindowOptions::default(), |_, cx| {
49 cx.new(|cx| MarkdownExample::new(MARKDOWN_EXAMPLE.into(), language_registry, cx))
50 })
51 .unwrap();
52 });
53}
54
55struct MarkdownExample {
56 markdown: Entity<Markdown>,
57}
58
59impl MarkdownExample {
60 pub fn new(text: SharedString, language_registry: Arc<LanguageRegistry>, cx: &mut App) -> Self {
61 let markdown = cx.new(|cx| {
62 Markdown::new(
63 text,
64 Some(language_registry),
65 Some("TypeScript".to_string()),
66 cx,
67 )
68 });
69 Self { markdown }
70 }
71}
72
73impl Render for MarkdownExample {
74 fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
75 let markdown_style = MarkdownStyle {
76 base_text_style: gpui::TextStyle {
77 font_family: "Zed Plex Sans".into(),
78 color: cx.theme().colors().terminal_ansi_black,
79 ..Default::default()
80 },
81 code_block: StyleRefinement::default()
82 .font_family("Zed Plex Mono")
83 .m(rems(1.))
84 .bg(rgb(0xAAAAAAA)),
85 inline_code: gpui::TextStyleRefinement {
86 font_family: Some("Zed Mono".into()),
87 color: Some(cx.theme().colors().editor_foreground),
88 background_color: Some(cx.theme().colors().editor_background),
89 ..Default::default()
90 },
91 rule_color: Color::Muted.color(cx),
92 block_quote_border_color: Color::Muted.color(cx),
93 block_quote: gpui::TextStyleRefinement {
94 color: Some(Color::Muted.color(cx)),
95 ..Default::default()
96 },
97 link: gpui::TextStyleRefinement {
98 color: Some(Color::Accent.color(cx)),
99 underline: Some(gpui::UnderlineStyle {
100 thickness: px(1.),
101 color: Some(Color::Accent.color(cx)),
102 wavy: false,
103 }),
104 ..Default::default()
105 },
106 syntax: cx.theme().syntax().clone(),
107 selection_background_color: {
108 let mut selection = cx.theme().players().local().selection;
109 selection.fade_out(0.7);
110 selection
111 },
112 ..Default::default()
113 };
114
115 div()
116 .id("markdown-example")
117 .debug_selector(|| "foo".into())
118 .relative()
119 .bg(gpui::white())
120 .size_full()
121 .p_4()
122 .overflow_y_scroll()
123 .child(MarkdownElement::new(self.markdown.clone(), markdown_style))
124 }
125}