mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-19 10:29:35 +03:00
Add Markdown Preview Toggle (#15215)
Add a "Preview Markdown" button to the quick action bar when in a markdown editor. While it isn't my favorite, I went with the basic eye icon to be a bit more generic so we can extend this control to allow opening other previews such as SVGs like @jansol mentioned. ![CleanShot 2024-07-26 at 11 02 16@2x](https://github.com/user-attachments/assets/415963ce-d19e-432d-b8c2-37e7c6e52683) https://github.com/user-attachments/assets/5980272c-eab9-4f69-86b6-0c593c25b525 --- Release Notes: - Added a button to preview Markdown files in the toolbar. `Option|Alt+Click` will open the preview to the side.
This commit is contained in:
parent
73d682c010
commit
05825e9804
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -8270,6 +8270,7 @@ dependencies = [
|
||||
"assistant",
|
||||
"editor",
|
||||
"gpui",
|
||||
"markdown_preview",
|
||||
"repl",
|
||||
"search",
|
||||
"settings",
|
||||
|
1
assets/icons/eye.svg
Normal file
1
assets/icons/eye.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-eye"><path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"/><circle cx="12" cy="12" r="3"/></svg>
|
After Width: | Height: | Size: 358 B |
1
assets/icons/file_code.svg
Normal file
1
assets/icons/file_code.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-code"><path d="M10 12.5 8 15l2 2.5"/><path d="m14 12.5 2 2.5-2 2.5"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z"/></svg>
|
After Width: | Height: | Size: 388 B |
1
assets/icons/file_text.svg
Normal file
1
assets/icons/file_text.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-file-text"><path d="M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z"/><path d="M14 2v4a2 2 0 0 0 2 2h4"/><path d="M10 9H8"/><path d="M16 13H8"/><path d="M16 17H8"/></svg>
|
After Width: | Height: | Size: 384 B |
@ -99,7 +99,7 @@ impl MarkdownPreviewView {
|
||||
.and_then(|view| pane.index_for_item(&view))
|
||||
}
|
||||
|
||||
fn resolve_active_item_as_markdown_editor(
|
||||
pub fn resolve_active_item_as_markdown_editor(
|
||||
workspace: &Workspace,
|
||||
cx: &mut ViewContext<Workspace>,
|
||||
) -> Option<View<Editor>> {
|
||||
@ -278,7 +278,7 @@ impl MarkdownPreviewView {
|
||||
}
|
||||
}
|
||||
|
||||
fn is_markdown_file<V>(editor: &View<Editor>, cx: &mut ViewContext<V>) -> bool {
|
||||
pub fn is_markdown_file<V>(editor: &View<Editor>, cx: &mut ViewContext<V>) -> bool {
|
||||
let language = editor.read(cx).buffer().read(cx).language_at(0, cx);
|
||||
language
|
||||
.map(|l| l.name().as_ref() == "Markdown")
|
||||
|
@ -16,12 +16,13 @@ doctest = false
|
||||
assistant.workspace = true
|
||||
editor.workspace = true
|
||||
gpui.workspace = true
|
||||
markdown_preview.workspace = true
|
||||
repl.workspace = true
|
||||
search.workspace = true
|
||||
settings.workspace = true
|
||||
ui.workspace = true
|
||||
util.workspace = true
|
||||
workspace.workspace = true
|
||||
repl.workspace = true
|
||||
zed_actions.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
|
@ -21,16 +21,18 @@ use workspace::{
|
||||
};
|
||||
|
||||
mod repl_menu;
|
||||
mod toggle_markdown_preview;
|
||||
|
||||
pub struct QuickActionBar {
|
||||
buffer_search_bar: View<BufferSearchBar>,
|
||||
repl_menu: Option<View<ContextMenu>>,
|
||||
toggle_settings_menu: Option<View<ContextMenu>>,
|
||||
toggle_selections_menu: Option<View<ContextMenu>>,
|
||||
active_item: Option<Box<dyn ItemHandle>>,
|
||||
_inlay_hints_enabled_subscription: Option<Subscription>,
|
||||
workspace: WeakView<Workspace>,
|
||||
active_item: Option<Box<dyn ItemHandle>>,
|
||||
buffer_search_bar: View<BufferSearchBar>,
|
||||
platform_style: PlatformStyle,
|
||||
repl_menu: Option<View<ContextMenu>>,
|
||||
show: bool,
|
||||
toggle_selections_menu: Option<View<ContextMenu>>,
|
||||
toggle_settings_menu: Option<View<ContextMenu>>,
|
||||
workspace: WeakView<Workspace>,
|
||||
}
|
||||
|
||||
impl QuickActionBar {
|
||||
@ -40,14 +42,15 @@ impl QuickActionBar {
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Self {
|
||||
let mut this = Self {
|
||||
buffer_search_bar,
|
||||
toggle_settings_menu: None,
|
||||
toggle_selections_menu: None,
|
||||
repl_menu: None,
|
||||
active_item: None,
|
||||
_inlay_hints_enabled_subscription: None,
|
||||
workspace: workspace.weak_handle(),
|
||||
active_item: None,
|
||||
buffer_search_bar,
|
||||
platform_style: PlatformStyle::platform(),
|
||||
repl_menu: None,
|
||||
show: true,
|
||||
toggle_selections_menu: None,
|
||||
toggle_settings_menu: None,
|
||||
workspace: workspace.weak_handle(),
|
||||
};
|
||||
this.apply_settings(cx);
|
||||
cx.observe_global::<SettingsStore>(|this, cx| this.apply_settings(cx))
|
||||
@ -300,22 +303,19 @@ impl Render for QuickActionBar {
|
||||
|
||||
h_flex()
|
||||
.id("quick action bar")
|
||||
.gap(Spacing::Large.rems(cx))
|
||||
.gap(Spacing::XXLarge.rems(cx))
|
||||
.child(
|
||||
h_flex()
|
||||
.gap(Spacing::Medium.rems(cx))
|
||||
.children(self.render_repl_menu(cx))
|
||||
.children(self.render_toggle_markdown_preview(self.workspace.clone(), cx))
|
||||
.children(search_button)
|
||||
.when(
|
||||
AssistantSettings::get_global(cx).enabled
|
||||
&& AssistantSettings::get_global(cx).button,
|
||||
|bar| bar.child(assistant_button),
|
||||
),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.gap(Spacing::Medium.rems(cx))
|
||||
.children(search_button),
|
||||
)
|
||||
.child(
|
||||
h_flex()
|
||||
.gap(Spacing::Medium.rems(cx))
|
||||
|
61
crates/quick_action_bar/src/toggle_markdown_preview.rs
Normal file
61
crates/quick_action_bar/src/toggle_markdown_preview.rs
Normal file
@ -0,0 +1,61 @@
|
||||
use gpui::{AnyElement, WeakView};
|
||||
use markdown_preview::{
|
||||
markdown_preview_view::MarkdownPreviewView, OpenPreview, OpenPreviewToTheSide,
|
||||
};
|
||||
use ui::{prelude::*, IconButtonShape, Tooltip};
|
||||
use workspace::Workspace;
|
||||
|
||||
use crate::QuickActionBar;
|
||||
|
||||
impl QuickActionBar {
|
||||
pub fn render_toggle_markdown_preview(
|
||||
&self,
|
||||
workspace: WeakView<Workspace>,
|
||||
cx: &mut ViewContext<Self>,
|
||||
) -> Option<AnyElement> {
|
||||
let mut active_editor_is_markdown = false;
|
||||
|
||||
if let Some(workspace) = self.workspace.upgrade() {
|
||||
workspace.update(cx, |workspace, cx| {
|
||||
active_editor_is_markdown =
|
||||
MarkdownPreviewView::resolve_active_item_as_markdown_editor(workspace, cx)
|
||||
.is_some();
|
||||
});
|
||||
}
|
||||
|
||||
if !active_editor_is_markdown {
|
||||
return None;
|
||||
}
|
||||
|
||||
let tooltip_meta = match self.platform_style {
|
||||
PlatformStyle::Mac => "Option+Click to open in a split",
|
||||
_ => "Alt+Click to open in a split",
|
||||
};
|
||||
|
||||
let button = IconButton::new("toggle-markdown-preview", IconName::Eye)
|
||||
.shape(IconButtonShape::Square)
|
||||
.icon_size(IconSize::Small)
|
||||
.style(ButtonStyle::Subtle)
|
||||
.tooltip(move |cx| {
|
||||
Tooltip::with_meta(
|
||||
"Preview Markdown",
|
||||
Some(&markdown_preview::OpenPreview),
|
||||
tooltip_meta,
|
||||
cx,
|
||||
)
|
||||
})
|
||||
.on_click(move |_, cx| {
|
||||
if let Some(workspace) = workspace.upgrade() {
|
||||
workspace.update(cx, |_, cx| {
|
||||
if cx.modifiers().alt {
|
||||
cx.dispatch_action(Box::new(OpenPreviewToTheSide));
|
||||
} else {
|
||||
cx.dispatch_action(Box::new(OpenPreview));
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Some(button.into_any_element())
|
||||
}
|
||||
}
|
@ -158,6 +158,7 @@ pub enum IconName {
|
||||
Exit,
|
||||
ExpandVertical,
|
||||
ExternalLink,
|
||||
Eye,
|
||||
File,
|
||||
FileDoc,
|
||||
FileGeneric,
|
||||
@ -166,6 +167,8 @@ pub enum IconName {
|
||||
FileRust,
|
||||
FileToml,
|
||||
FileTree,
|
||||
FileText,
|
||||
FileCode,
|
||||
Filter,
|
||||
Folder,
|
||||
FolderOpen,
|
||||
@ -309,6 +312,7 @@ impl IconName {
|
||||
IconName::Exit => "icons/exit.svg",
|
||||
IconName::ExpandVertical => "icons/expand_vertical.svg",
|
||||
IconName::ExternalLink => "icons/external_link.svg",
|
||||
IconName::Eye => "icons/eye.svg",
|
||||
IconName::File => "icons/file.svg",
|
||||
IconName::FileDoc => "icons/file_icons/book.svg",
|
||||
IconName::FileGeneric => "icons/file_icons/file.svg",
|
||||
@ -317,6 +321,8 @@ impl IconName {
|
||||
IconName::FileRust => "icons/file_icons/rust.svg",
|
||||
IconName::FileToml => "icons/file_icons/toml.svg",
|
||||
IconName::FileTree => "icons/project.svg",
|
||||
IconName::FileCode => "icons/file_code.svg",
|
||||
IconName::FileText => "icons/file_text.svg",
|
||||
IconName::Filter => "icons/filter.svg",
|
||||
IconName::Folder => "icons/file_icons/folder.svg",
|
||||
IconName::FolderOpen => "icons/file_icons/folder_open.svg",
|
||||
|
Loading…
Reference in New Issue
Block a user