diff --git a/src/features/command-palette/components/command-palette.tsx b/src/features/command-palette/components/command-palette.tsx index 33d5eb2f..8ab27836 100644 --- a/src/features/command-palette/components/command-palette.tsx +++ b/src/features/command-palette/components/command-palette.tsx @@ -31,6 +31,7 @@ import KeybindingBadge from "@/ui/keybinding-badge"; import { createAdvancedActions } from "../constants/advanced-actions"; import { createFileActions } from "../constants/file-actions"; import { createGitActions } from "../constants/git-actions"; +import { createMarkdownActions } from "../constants/markdown-actions"; import { createNavigationActions } from "../constants/navigation-actions"; import { createSettingsActions } from "../constants/settings-actions"; import { createViewActions } from "../constants/view-actions"; @@ -78,6 +79,7 @@ const CommandPalette = () => { const { showToast } = useToast(); const buffers = useBufferStore.use.buffers(); const activeBufferId = useBufferStore.use.activeBufferId(); + const activeBuffer = buffers.find((b) => b.id === activeBufferId) || null; const { closeBuffer, setActiveBuffer, @@ -86,9 +88,23 @@ const CommandPalette = () => { reopenClosedTab, } = useBufferStore.use.actions(); const { zoomIn, zoomOut, resetZoom } = useZoomStore.use.actions(); + const { openBuffer } = useBufferStore.use.actions(); + + // Helper function to check if the active buffer is a markdown file + const isMarkdownFile = () => { + if (!activeBuffer) return false; + const extension = activeBuffer.path.split(".").pop()?.toLowerCase(); + return extension === "md" || extension === "markdown"; + }; // Create all actions using factory functions const allActions: Action[] = [ + ...createMarkdownActions({ + isMarkdownFile: isMarkdownFile(), + activeBuffer, + openBuffer, + onClose, + }), ...createViewActions({ isSidebarVisible, setIsSidebarVisible, diff --git a/src/features/command-palette/constants/markdown-actions.tsx b/src/features/command-palette/constants/markdown-actions.tsx new file mode 100644 index 00000000..03593299 --- /dev/null +++ b/src/features/command-palette/constants/markdown-actions.tsx @@ -0,0 +1,59 @@ +import { Eye } from "lucide-react"; +import type { Buffer } from "@/features/editor/stores/buffer-store"; +import type { Action } from "../models/action.types"; + +interface MarkdownActionsParams { + isMarkdownFile: boolean; + activeBuffer: Buffer | null; + openBuffer: ( + path: string, + name: string, + content: string, + isImage?: boolean, + isSQLite?: boolean, + isDiff?: boolean, + isVirtual?: boolean, + diffData?: any, + isMarkdownPreview?: boolean, + sourceFilePath?: string, + ) => string; + onClose: () => void; +} + +export const createMarkdownActions = (params: MarkdownActionsParams): Action[] => { + const { isMarkdownFile, activeBuffer, openBuffer, onClose } = params; + + if (!isMarkdownFile || !activeBuffer) { + return []; + } + + return [ + { + id: "markdown-preview", + label: "Markdown: Preview Markdown", + description: "Open markdown preview in a new tab", + icon: , + category: "Markdown", + action: () => { + // Create a virtual path for the preview + const previewPath = `${activeBuffer.path}:preview`; + const previewName = `${activeBuffer.name} (Preview)`; + + // Open a new buffer for the preview + openBuffer( + previewPath, + previewName, + activeBuffer.content, + false, // isImage + false, // isSQLite + false, // isDiff + true, // isVirtual + undefined, // diffData + true, // isMarkdownPreview + activeBuffer.path, // sourceFilePath + ); + onClose(); + }, + }, + ]; +}; diff --git a/src/features/command-palette/models/action.types.ts b/src/features/command-palette/models/action.types.ts index 3d876407..fb907b53 100644 --- a/src/features/command-palette/models/action.types.ts +++ b/src/features/command-palette/models/action.types.ts @@ -10,4 +10,4 @@ export interface Action { action: () => void; } -export type ActionCategory = "View" | "Settings" | "File" | "Window" | "Navigation"; +export type ActionCategory = "View" | "Settings" | "File" | "Window" | "Navigation" | "Markdown"; diff --git a/src/features/editor/components/code-editor.tsx b/src/features/editor/components/code-editor.tsx index c1e9846a..f649e788 100644 --- a/src/features/editor/components/code-editor.tsx +++ b/src/features/editor/components/code-editor.tsx @@ -13,7 +13,6 @@ import { useAppStore } from "@/stores/app-store"; import { useZoomStore } from "@/stores/zoom-store"; import { HoverTooltip } from "../lsp/hover-tooltip"; import { MarkdownPreview } from "../markdown/markdown-preview"; -import { isMarkdownFile } from "../utils/lines"; import { Editor } from "./editor"; import { EditorStylesheet } from "./stylesheet"; import Breadcrumb from "./toolbar/breadcrumb"; @@ -41,7 +40,6 @@ const CodeEditor = ({ className }: CodeEditorProps) => { const { setRefs, setContent, setFileInfo } = useEditorStateStore.use.actions(); // No longer need to sync content - editor-view-store computes from buffer const { setDisabled } = useEditorSettingsStore.use.actions(); - const isMarkdownPreview = useEditorSettingsStore.use.isMarkdownPreview(); const buffers = useBufferStore.use.buffers(); const activeBufferId = useBufferStore.use.activeBufferId(); @@ -61,8 +59,7 @@ const CodeEditor = ({ className }: CodeEditorProps) => { const filePath = activeBuffer?.path || ""; const onChange = activeBuffer ? handleContentChange : () => {}; - const showMarkdownPreview = - activeBuffer && isMarkdownFile(activeBuffer.path) && isMarkdownPreview; + const showMarkdownPreview = activeBuffer?.isMarkdownPreview || false; // Initialize refs in store useEffect(() => { diff --git a/src/features/editor/components/toolbar/breadcrumb.tsx b/src/features/editor/components/toolbar/breadcrumb.tsx index c5abf1ec..ef2c1ede 100644 --- a/src/features/editor/components/toolbar/breadcrumb.tsx +++ b/src/features/editor/components/toolbar/breadcrumb.tsx @@ -1,10 +1,9 @@ -import { ArrowLeft, ChevronRight, Eye, Search, Sparkles } from "lucide-react"; +import { ArrowLeft, ChevronRight, Search, Sparkles } from "lucide-react"; import { type RefObject, useRef, useState } from "react"; import { createPortal } from "react-dom"; import { useEventListener, useOnClickOutside } from "usehooks-ts"; import { EDITOR_CONSTANTS } from "@/features/editor/config/constants"; import { useBufferStore } from "@/features/editor/stores/buffer-store"; -import { useEditorSettingsStore } from "@/features/editor/stores/settings-store"; import { useEditorStateStore } from "@/features/editor/stores/state-store"; import { logger } from "@/features/editor/utils/logger"; import FileIcon from "@/features/file-explorer/views/file.icon"; @@ -28,8 +27,6 @@ export default function Breadcrumb() { const activeBuffer = buffers.find((b) => b.id === activeBufferId) || null; const { rootFolderPath, handleFileSelect } = useFileSystemStore(); const { isFindVisible, setIsFindVisible } = useUIState(); - const isMarkdownPreview = useEditorSettingsStore.use.isMarkdownPreview(); - const { setIsMarkdownPreview } = useEditorSettingsStore.use.actions(); const { toggle: toggleInlineEditToolbar } = useInlineEditToolbarStore.use.actions(); const selection = useEditorStateStore.use.selection?.(); @@ -45,22 +42,12 @@ export default function Breadcrumb() { setIsFindVisible(!isFindVisible); }; - const handlePreviewClick = () => { - setIsMarkdownPreview(!isMarkdownPreview); - }; - const handleInlineEditClick = () => { toggleInlineEditToolbar(); }; const hasSelection = selection && selection.start.offset !== selection.end.offset; - const isMarkdownFile = () => { - if (!activeBuffer) return false; - const extension = activeBuffer.path.split(".").pop()?.toLowerCase(); - return extension === "md" || extension === "markdown"; - }; - const filePath = activeBuffer?.path || ""; const rootPath = rootFolderPath; const onNavigate = handleNavigate; @@ -232,17 +219,6 @@ export default function Breadcrumb() { ))}
- {isMarkdownFile() && ( - - )}