From e752ec1a92642a645ff371c7d31bda013693cfd3 Mon Sep 17 00:00:00 2001 From: Danilo Leal <67129314+danilo-leal@users.noreply.github.com> Date: Wed, 28 Jan 2026 00:19:13 -0300 Subject: [PATCH] Add item for opening Markdown/SVG files in preview tab in right-click menu (#47821) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Following user feedback, this should help making the Markdown Preview more discoverable. | Buffer Right-click | Tab Right-click | |--------|--------| | Screenshot 2026-01-27 at 10 
16@2x | Screenshot 2026-01-27 at 10 
16 2@2x | 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 + .../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(-) diff --git a/Cargo.lock b/Cargo.lock index 0989967dd5696e667b6b4a4f7477e52469834ce9..fdc2a0c224167de908eedf4921d898169a365df4 100644 --- a/Cargo.lock +++ b/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]] diff --git a/crates/editor/src/items.rs b/crates/editor/src/items.rs index 14b736acff64ac855b79ce54dcb56d09c7afb868..047be5b9f29d4e20a1047e0366b6f554264547f5 100644 --- a/crates/editor/src/items.rs +++ b/crates/editor/src/items.rs @@ -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, + ) -> Vec<(SharedString, Box)> { + 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, + )); + } + + if is_svg { + actions.push(( + "Open SVG Preview".into(), + Box::new(OpenSvgPreview) as Box, + )); + } + + actions + } + fn preserve_preview(&self, cx: &App) -> bool { self.buffer.read(cx).preserve_preview(cx) } diff --git a/crates/editor/src/mouse_context_menu.rs b/crates/editor/src/mouse_context_menu.rs index ae1d81da50511ecd61b3e6342ac71351feb1f41b..2cc050dae8be73fda89a6b9982b052bddd639063 100644 --- a/crates/editor/src/mouse_context_menu.rs +++ b/crates/editor/src/mouse_context_menu.rs @@ -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", diff --git a/crates/markdown_preview/Cargo.toml b/crates/markdown_preview/Cargo.toml index d61ec00cc8cfd5e04768381b64d5230682924623..c9cce94de1f10ac85a93663dea09a947586da282 100644 --- a/crates/markdown_preview/Cargo.toml +++ b/crates/markdown_preview/Cargo.toml @@ -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"] } diff --git a/crates/markdown_preview/src/markdown_preview.rs b/crates/markdown_preview/src/markdown_preview.rs index 61c99764add0a96135730d3cccfe4ef744a63d40..c7e8e9e9272e196da25be086640316129fb819bd 100644 --- a/crates/markdown_preview/src/markdown_preview.rs +++ b/crates/markdown_preview/src/markdown_preview.rs @@ -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 ] diff --git a/crates/svg_preview/Cargo.toml b/crates/svg_preview/Cargo.toml index 18f55e28d5d1364d75492455508bb34a5e24422b..9ee085ee07355a3f5c8cf31768b44610be7b50dd 100644 --- a/crates/svg_preview/Cargo.toml +++ b/crates/svg_preview/Cargo.toml @@ -18,3 +18,4 @@ gpui.workspace = true language.workspace = true ui.workspace = true workspace.workspace = true +zed_actions.workspace = true diff --git a/crates/svg_preview/src/svg_preview.rs b/crates/svg_preview/src/svg_preview.rs index ca1891394d693b5a9817fcc43f462a4f611b94f2..060639db5fa29a552bd606dca0c470aab5116a43 100644 --- a/crates/svg_preview/src/svg_preview.rs +++ b/crates/svg_preview/src/svg_preview.rs @@ -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 ] diff --git a/crates/zed_actions/src/lib.rs b/crates/zed_actions/src/lib.rs index 1d3e8fabeec0cd05480a332ef65fdc288adc9654..84746cfb03ebf9c86b1d6206175201630005b9e1 100644 --- a/crates/zed_actions/src/lib.rs +++ b/crates/zed_actions/src/lib.rs @@ -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, + ] + ); + } +}