1use assets::Assets;
2use gpui::{prelude::*, App, KeyBinding, Task, View, WindowOptions};
3use language::{language_settings::AllLanguageSettings, LanguageRegistry};
4use markdown::{Markdown, MarkdownStyle};
5use node_runtime::FakeNodeRuntime;
6use settings::SettingsStore;
7use std::sync::Arc;
8use theme::LoadThemes;
9use ui::prelude::*;
10use ui::{div, WindowContext};
11
12const MARKDOWN_EXAMPLE: &'static 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## Emphasis
19Emphasis can be added with italics or bold. *This text will be italic*. _This will also be italic_
20
21## Lists
22
23### Unordered Lists
24Unordered lists use asterisks `*`, plus `+`, or minus `-` as list markers.
25
26* Item 1
27* Item 2
28 * Item 2a
29 * Item 2b
30
31### Ordered Lists
32Ordered lists use numbers followed by a period.
33
341. Item 1
352. Item 2
363. Item 3
37 1. Item 3a
38 2. Item 3b
39
40## Links
41Links are created using the format [http://zed.dev](https://zed.dev).
42
43They can also be detected automatically, for example https://zed.dev/blog.
44
45## Images
46Images are like links, but with an exclamation mark `!` in front.
47
48```todo!
49
50```
51
52## Code
53Inline `code` can be wrapped with backticks `` ` ``.
54
55```markdown
56Inline `code` has `back-ticks around` it.
57```
58
59Code blocks can be created by indenting lines by four spaces or with triple backticks ```.
60
61```javascript
62function test() {
63 console.log("notice the blank line before this function?");
64}
65```
66
67## Blockquotes
68Blockquotes are created with `>`.
69
70> This is a blockquote.
71
72## Horizontal Rules
73Horizontal rules are created using three or more asterisks `***`, dashes `---`, or underscores `___`.
74
75## Line breaks
76This is a
77\
78line break!
79
80---
81
82Remember, 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.
83"#;
84
85pub fn main() {
86 env_logger::init();
87 App::new().with_assets(Assets).run(|cx| {
88 let store = SettingsStore::test(cx);
89 cx.set_global(store);
90 language::init(cx);
91 SettingsStore::update(cx, |store, cx| {
92 store.update_user_settings::<AllLanguageSettings>(cx, |_| {});
93 });
94 cx.bind_keys([KeyBinding::new("cmd-c", markdown::Copy, None)]);
95
96 let node_runtime = FakeNodeRuntime::new();
97 let language_registry = Arc::new(LanguageRegistry::new(
98 Task::ready(()),
99 cx.background_executor().clone(),
100 ));
101 languages::init(language_registry.clone(), node_runtime, cx);
102 theme::init(LoadThemes::JustBase, cx);
103 Assets.load_fonts(cx).unwrap();
104
105 cx.activate(true);
106 cx.open_window(WindowOptions::default(), |cx| {
107 cx.new_view(|cx| {
108 MarkdownExample::new(
109 MARKDOWN_EXAMPLE.to_string(),
110 MarkdownStyle {
111 code_block: gpui::TextStyleRefinement {
112 font_family: Some("Zed Mono".into()),
113 color: Some(cx.theme().colors().editor_foreground),
114 background_color: Some(cx.theme().colors().editor_background),
115 ..Default::default()
116 },
117 inline_code: gpui::TextStyleRefinement {
118 font_family: Some("Zed Mono".into()),
119 // @nate: Could we add inline-code specific styles to the theme?
120 color: Some(cx.theme().colors().editor_foreground),
121 background_color: Some(cx.theme().colors().editor_background),
122 ..Default::default()
123 },
124 rule_color: Color::Muted.color(cx),
125 block_quote_border_color: Color::Muted.color(cx),
126 block_quote: gpui::TextStyleRefinement {
127 color: Some(Color::Muted.color(cx)),
128 ..Default::default()
129 },
130 link: gpui::TextStyleRefinement {
131 color: Some(Color::Accent.color(cx)),
132 underline: Some(gpui::UnderlineStyle {
133 thickness: px(1.),
134 color: Some(Color::Accent.color(cx)),
135 wavy: false,
136 }),
137 ..Default::default()
138 },
139 syntax: cx.theme().syntax().clone(),
140 selection_background_color: {
141 let mut selection = cx.theme().players().local().selection;
142 selection.fade_out(0.7);
143 selection
144 },
145 },
146 language_registry,
147 cx,
148 )
149 })
150 })
151 .unwrap();
152 });
153}
154
155struct MarkdownExample {
156 markdown: View<Markdown>,
157}
158
159impl MarkdownExample {
160 pub fn new(
161 text: String,
162 style: MarkdownStyle,
163 language_registry: Arc<LanguageRegistry>,
164 cx: &mut WindowContext,
165 ) -> Self {
166 let markdown = cx.new_view(|cx| Markdown::new(text, style, Some(language_registry), cx));
167 Self { markdown }
168 }
169}
170
171impl Render for MarkdownExample {
172 fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
173 div()
174 .id("markdown-example")
175 .debug_selector(|| "foo".into())
176 .relative()
177 .bg(gpui::white())
178 .size_full()
179 .p_4()
180 .overflow_y_scroll()
181 .child(self.markdown.clone())
182 }
183}