Cargo.lock 🔗
@@ -9857,6 +9857,7 @@ dependencies = [
"urlencoding",
"util",
"workspace",
+ "zed_actions",
]
[[package]]
@@ -16155,6 +16156,7 @@ dependencies = [
"multi_buffer",
"ui",
"workspace",
+ "zed_actions",
]
[[package]]
Danilo Leal created
Following user feedback, this should help making the Markdown Preview
more discoverable.
| Buffer Right-click | Tab Right-click |
|--------|--------|
| <img width="2474" height="1824" alt="Screenshot 2026-01-27 at 10
16@2x"
src="https://github.com/user-attachments/assets/251149e9-89c6-4d11-aed0-872669939cfb"
/> | <img width="2464" height="1808" alt="Screenshot 2026-01-27 at 10
16 2@2x"
src="https://github.com/user-attachments/assets/359a221b-2141-45b1-98a9-d9c77b601c0b"
/> |
Release Notes:
- Workspace: Added a menu item in the buffer and tab right-click menu
for opening Markdown and SVG files in the preview tab.
Cargo.lock | 2
crates/editor/src/items.rs | 45 +++++++++++++++++++
crates/editor/src/mouse_context_menu.rs | 27 +++++++++++
crates/markdown_preview/Cargo.toml | 1
crates/markdown_preview/src/markdown_preview.rs | 6 -
crates/svg_preview/Cargo.toml | 1
crates/svg_preview/src/svg_preview.rs | 6 -
crates/zed_actions/src/lib.rs | 30 ++++++++++++
8 files changed, 110 insertions(+), 8 deletions(-)
@@ -9857,6 +9857,7 @@ dependencies = [
"urlencoding",
"util",
"workspace",
+ "zed_actions",
]
[[package]]
@@ -16155,6 +16156,7 @@ dependencies = [
"multi_buffer",
"ui",
"workspace",
+ "zed_actions",
]
[[package]]
@@ -59,6 +59,9 @@ use workspace::{
item::{BreadcrumbText, FollowEvent, ProjectItemKind},
searchable::SearchOptions,
};
+use zed_actions::preview::{
+ markdown::OpenPreview as OpenMarkdownPreview, svg::OpenPreview as OpenSvgPreview,
+};
pub const MAX_TAB_TITLE_LEN: usize = 24;
@@ -1033,6 +1036,48 @@ impl Item for Editor {
}
}
+ fn tab_extra_context_menu_actions(
+ &self,
+ _window: &mut Window,
+ cx: &mut Context<Self>,
+ ) -> Vec<(SharedString, Box<dyn gpui::Action>)> {
+ let mut actions = Vec::new();
+
+ let is_markdown = self
+ .buffer()
+ .read(cx)
+ .as_singleton()
+ .and_then(|buffer| buffer.read(cx).language())
+ .is_some_and(|language| language.name().as_ref() == "Markdown");
+
+ let is_svg = self
+ .buffer()
+ .read(cx)
+ .as_singleton()
+ .and_then(|buffer| buffer.read(cx).file())
+ .is_some_and(|file| {
+ std::path::Path::new(file.file_name(cx))
+ .extension()
+ .is_some_and(|ext| ext.eq_ignore_ascii_case("svg"))
+ });
+
+ if is_markdown {
+ actions.push((
+ "Open Markdown Preview".into(),
+ Box::new(OpenMarkdownPreview) as Box<dyn gpui::Action>,
+ ));
+ }
+
+ if is_svg {
+ actions.push((
+ "Open SVG Preview".into(),
+ Box::new(OpenSvgPreview) as Box<dyn gpui::Action>,
+ ));
+ }
+
+ actions
+ }
+
fn preserve_preview(&self, cx: &App) -> bool {
self.buffer.read(cx).preserve_preview(cx)
}
@@ -14,6 +14,9 @@ use std::ops::Range;
use text::PointUtf16;
use workspace::OpenInTerminal;
use zed_actions::agent::AddSelectionToThread;
+use zed_actions::preview::{
+ markdown::OpenPreview as OpenMarkdownPreview, svg::OpenPreview as OpenSvgPreview,
+};
#[derive(Debug)]
pub enum MenuPosition {
@@ -218,6 +221,24 @@ pub fn deploy_context_menu(
let run_to_cursor = window.is_action_available(&RunToCursor, cx);
let disable_ai = DisableAiSettings::get_global(cx).disable_ai;
+ let is_markdown = editor
+ .buffer()
+ .read(cx)
+ .as_singleton()
+ .and_then(|buffer| buffer.read(cx).language())
+ .is_some_and(|language| language.name().as_ref() == "Markdown");
+
+ let is_svg = editor
+ .buffer()
+ .read(cx)
+ .as_singleton()
+ .and_then(|buffer| buffer.read(cx).file())
+ .is_some_and(|file| {
+ std::path::Path::new(file.file_name(cx))
+ .extension()
+ .is_some_and(|ext| ext.eq_ignore_ascii_case("svg"))
+ });
+
ui::ContextMenu::build(window, cx, |menu, _window, _cx| {
let builder = menu
.on_blur_subscription(Subscription::new(|| {}))
@@ -272,6 +293,12 @@ pub fn deploy_context_menu(
},
Box::new(RevealInFileManager),
)
+ .when(is_markdown, |builder| {
+ builder.action("Open Markdown Preview", Box::new(OpenMarkdownPreview))
+ })
+ .when(is_svg, |builder| {
+ builder.action("Open SVG Preview", Box::new(OpenSvgPreview))
+ })
.action_disabled_when(
!has_reveal_target,
"Open in Terminal",
@@ -34,6 +34,7 @@ ui.workspace = true
urlencoding.workspace = true
util.workspace = true
workspace.workspace = true
+zed_actions.workspace = true
[dev-dependencies]
editor = { workspace = true, features = ["test-support"] }
@@ -7,6 +7,8 @@ pub mod markdown_parser;
pub mod markdown_preview_view;
pub mod markdown_renderer;
+pub use zed_actions::preview::markdown::{OpenPreview, OpenPreviewToTheSide};
+
actions!(
markdown,
[
@@ -24,10 +26,6 @@ actions!(
ScrollUpByItem,
/// Scrolls down by one markdown element in the markdown preview
ScrollDownByItem,
- /// Opens a markdown preview for the current file.
- OpenPreview,
- /// Opens a markdown preview in a split pane.
- OpenPreviewToTheSide,
/// Opens a following markdown preview that syncs with the editor.
OpenFollowingPreview
]
@@ -18,3 +18,4 @@ gpui.workspace = true
language.workspace = true
ui.workspace = true
workspace.workspace = true
+zed_actions.workspace = true
@@ -3,13 +3,11 @@ use workspace::Workspace;
pub mod svg_preview_view;
+pub use zed_actions::preview::svg::{OpenPreview, OpenPreviewToTheSide};
+
actions!(
svg,
[
- /// Opens an SVG preview for the current file.
- OpenPreview,
- /// Opens an SVG preview in a split pane.
- OpenPreviewToTheSide,
/// Opens a following SVG preview that syncs with the editor.
OpenFollowingPreview
]
@@ -651,3 +651,33 @@ pub mod wsl_actions {
pub create_new_window: bool,
}
}
+
+pub mod preview {
+ pub mod markdown {
+ use gpui::actions;
+
+ actions!(
+ markdown,
+ [
+ /// Opens a markdown preview for the current file.
+ OpenPreview,
+ /// Opens a markdown preview in a split pane.
+ OpenPreviewToTheSide,
+ ]
+ );
+ }
+
+ pub mod svg {
+ use gpui::actions;
+
+ actions!(
+ svg,
+ [
+ /// Opens an SVG preview for the current file.
+ OpenPreview,
+ /// Opens an SVG preview in a split pane.
+ OpenPreviewToTheSide,
+ ]
+ );
+ }
+}