@@ -20,7 +20,7 @@ use workspace::{Pane, Workspace};
use crate::OpenPreviewToTheSide;
use crate::markdown_elements::ParsedMarkdownElement;
use crate::{
- OpenPreview,
+ OpenFollowingPreview, OpenPreview,
markdown_elements::ParsedMarkdown,
markdown_parser::parse_markdown,
markdown_renderer::{RenderContext, render_markdown_block},
@@ -39,6 +39,7 @@ pub struct MarkdownPreviewView {
tab_content_text: Option<SharedString>,
language_registry: Arc<LanguageRegistry>,
parsing_markdown_task: Option<Task<Result<()>>>,
+ mode: MarkdownPreviewMode,
}
#[derive(Clone, Copy, Debug, PartialEq)]
@@ -58,9 +59,11 @@ impl MarkdownPreviewView {
pub fn register(workspace: &mut Workspace, _window: &mut Window, _cx: &mut Context<Workspace>) {
workspace.register_action(move |workspace, _: &OpenPreview, window, cx| {
if let Some(editor) = Self::resolve_active_item_as_markdown_editor(workspace, cx) {
- let view = Self::create_markdown_view(workspace, editor, window, cx);
+ let view = Self::create_markdown_view(workspace, editor.clone(), window, cx);
workspace.active_pane().update(cx, |pane, cx| {
- if let Some(existing_view_idx) = Self::find_existing_preview_item_idx(pane) {
+ if let Some(existing_view_idx) =
+ Self::find_existing_independent_preview_item_idx(pane, &editor, cx)
+ {
pane.activate_item(existing_view_idx, true, true, window, cx);
} else {
pane.add_item(Box::new(view.clone()), true, true, None, window, cx)
@@ -84,7 +87,9 @@ impl MarkdownPreviewView {
)
});
pane.update(cx, |pane, cx| {
- if let Some(existing_view_idx) = Self::find_existing_preview_item_idx(pane) {
+ if let Some(existing_view_idx) =
+ Self::find_existing_independent_preview_item_idx(pane, &editor, cx)
+ {
pane.activate_item(existing_view_idx, true, true, window, cx);
} else {
pane.add_item(Box::new(view.clone()), false, false, None, window, cx)
@@ -94,11 +99,49 @@ impl MarkdownPreviewView {
cx.notify();
}
});
+
+ workspace.register_action(move |workspace, _: &OpenFollowingPreview, window, cx| {
+ if let Some(editor) = Self::resolve_active_item_as_markdown_editor(workspace, cx) {
+ // Check if there's already a following preview
+ let existing_follow_view_idx = {
+ let active_pane = workspace.active_pane().read(cx);
+ active_pane
+ .items_of_type::<MarkdownPreviewView>()
+ .find(|view| view.read(cx).mode == MarkdownPreviewMode::Follow)
+ .and_then(|view| active_pane.index_for_item(&view))
+ };
+
+ if let Some(existing_follow_view_idx) = existing_follow_view_idx {
+ workspace.active_pane().update(cx, |pane, cx| {
+ pane.activate_item(existing_follow_view_idx, true, true, window, cx);
+ });
+ } else {
+ let view =
+ Self::create_following_markdown_view(workspace, editor.clone(), window, cx);
+ workspace.active_pane().update(cx, |pane, cx| {
+ pane.add_item(Box::new(view.clone()), true, true, None, window, cx)
+ });
+ }
+ cx.notify();
+ }
+ });
}
- fn find_existing_preview_item_idx(pane: &Pane) -> Option<usize> {
+ fn find_existing_independent_preview_item_idx(
+ pane: &Pane,
+ editor: &Entity<Editor>,
+ cx: &App,
+ ) -> Option<usize> {
pane.items_of_type::<MarkdownPreviewView>()
- .nth(0)
+ .find(|view| {
+ let view_read = view.read(cx);
+ // Only look for independent (Default mode) previews, not Follow previews
+ view_read.mode == MarkdownPreviewMode::Default
+ && view_read
+ .active_editor
+ .as_ref()
+ .is_some_and(|active_editor| active_editor.editor == *editor)
+ })
.and_then(|view| pane.index_for_item(&view))
}
@@ -122,6 +165,25 @@ impl MarkdownPreviewView {
editor: Entity<Editor>,
window: &mut Window,
cx: &mut Context<Workspace>,
+ ) -> Entity<MarkdownPreviewView> {
+ let language_registry = workspace.project().read(cx).languages().clone();
+ let workspace_handle = workspace.weak_handle();
+ MarkdownPreviewView::new(
+ MarkdownPreviewMode::Default,
+ editor,
+ workspace_handle,
+ language_registry,
+ None,
+ window,
+ cx,
+ )
+ }
+
+ fn create_following_markdown_view(
+ workspace: &mut Workspace,
+ editor: Entity<Editor>,
+ window: &mut Window,
+ cx: &mut Context<Workspace>,
) -> Entity<MarkdownPreviewView> {
let language_registry = workspace.project().read(cx).languages().clone();
let workspace_handle = workspace.weak_handle();
@@ -266,6 +328,7 @@ impl MarkdownPreviewView {
language_registry,
parsing_markdown_task: None,
image_cache: RetainAllImageCache::new(cx),
+ mode,
};
this.set_editor(active_editor, window, cx);
@@ -343,6 +406,7 @@ impl MarkdownPreviewView {
);
let tab_content = editor.read(cx).tab_content_text(0, cx);
+
if self.tab_content_text.is_none() {
self.tab_content_text = Some(format!("Preview {}", tab_content).into());
}