From 88e9a5290d4d0b8fa548961c76d745e19c78b85e Mon Sep 17 00:00:00 2001 From: Amit Haridas Date: Wed, 3 Jun 2026 20:44:00 +0530 Subject: [PATCH] fix(renderer): add ensureEditor fallback and fix pandoc export path 1. Source editor blank: Added ensureEditor() method with try-catch that lazily creates the CodeMirror editor when setEditorContent is called if the initial DOMContentLoaded creation failed or was skipped. Replaced inline createEditor calls in createTabElements and DOMContentLoaded with ensureEditor(). 2. Export via pandoc failing: runPandocCmd parsed the full path /bin/linux/pandoc as the command, then prepended it to args because parsed.command !== 'pandoc'. This caused pandoc to receive its own binary path as the first input file. Fix: use path.basename() to check if the command ends with 'pandoc' (or 'pandoc.exe'). Amit Haridas --- src/main.js | 4 ++- src/renderer.js | 95 ++++++++++++++++++++++--------------------------- 2 files changed, 45 insertions(+), 54 deletions(-) diff --git a/src/main.js b/src/main.js index 863ab5b..1d7868f 100644 --- a/src/main.js +++ b/src/main.js @@ -242,7 +242,9 @@ function runPandoc(args, callback) { function runPandocCmd(cmdString, callback) { const parsed = parseCommand(cmdString); // Skip 'pandoc' if it's the first element (command itself) - const args = parsed.command === 'pandoc' ? parsed.args : [parsed.command, ...parsed.args]; + // Use path.basename to handle full paths like bin/linux/pandoc + const cmdBase = path.basename(parsed.command).replace(/\.exe$/i, ''); + const args = cmdBase === 'pandoc' ? parsed.args : [parsed.command, ...parsed.args]; const pandocPath = getPandocPath(); execFile(pandocPath, args, { maxBuffer: 10 * 1024 * 1024 }, callback); } diff --git a/src/renderer.js b/src/renderer.js index b0adf90..c39cb6f 100644 --- a/src/renderer.js +++ b/src/renderer.js @@ -490,38 +490,7 @@ class TabManager { document.querySelector('.editor-container').appendChild(tabContent); // Initialize CodeMirror editor - const editorContainer = document.getElementById(`editor-cm-${tab.id}`); - if (editorContainer) { - const isDark = document.body.className.includes('dark'); - tab.editorView = createEditor(editorContainer, { - content: tab.content, - onChange: (newContent) => { - tab.content = newContent; - tab.isDirty = true; - // Dynamically enable/disable Large File Mode on edit - if (newContent.length > 1024 * 1024) { - if (!tab.largeFileMode) { - tab.largeFileMode = true; - this.isPreviewVisible = false; - this.updatePreviewVisibility(); - notifyUser('Large content detected (>1MB). Large File Mode enabled to maintain peak responsiveness. Live preview auto-render is disabled.', 'warning'); - } - } else { - tab.largeFileMode = false; - } - this.updatePreview(tab.id); - this.updateWordCount(); - this.updateTabBar(); - if (outlinePanelContainer?._refreshOutline) outlinePanelContainer._refreshOutline(); - }, - onUpdate: (view) => { - this.updateCursorPosition(view); - if (outlinePanelContainer?._setActiveHeading) outlinePanelContainer._setActiveHeading(view.state.doc.lineAt(view.state.selection.main.head).number); - }, - isDark, - showLineNumbers: this.showLineNumbers, - }); - } + this.ensureEditor(tab); } switchToTab(tabId) { @@ -1492,9 +1461,47 @@ class TabManager { return tab?.content || ''; } + // Ensure a tab has a CodeMirror editor (lazy creation fallback) + ensureEditor(tab) { + if (tab.editorView) return true; + const editorContainer = document.getElementById(`editor-cm-${tab.id}`); + if (!editorContainer) { + console.error(`[ensureEditor] editor-cm-${tab.id} not found in DOM`); + return false; + } + try { + const isDark = document.body.className.includes('dark'); + tab.editorView = createEditor(editorContainer, { + content: tab.content, + onChange: (newContent) => { + tab.content = newContent; + tab.isDirty = true; + this.updatePreview(tab.id); + this.updateWordCount(); + this.updateTabBar(); + if (outlinePanelContainer?._refreshOutline) outlinePanelContainer._refreshOutline(); + }, + onUpdate: (view) => { + this.updateCursorPosition(view); + if (outlinePanelContainer?._setActiveHeading) outlinePanelContainer._setActiveHeading(view.state.doc.lineAt(view.state.selection.main.head).number); + }, + isDark, + showLineNumbers: this.showLineNumbers, + }); + console.log(`[ensureEditor] Created editor for tab ${tab.id}`); + return true; + } catch (err) { + console.error(`[ensureEditor] Failed to create editor for tab ${tab.id}:`, err); + return false; + } + } + // Set content in editor setEditorContent(tabId, content) { const tab = this.tabs.get(tabId); + if (!tab?.editorView) { + this.ensureEditor(tab); + } if (tab?.editorView) { tab.editorView.dispatch({ changes: { from: 0, to: tab.editorView.state.doc.length, insert: content } @@ -1908,27 +1915,9 @@ document.addEventListener('DOMContentLoaded', async () => { }); // Initialize CodeMirror for the initial tab (tab 1) - const initialEditorContainer = document.getElementById('editor-cm-1'); - if (initialEditorContainer) { - const tab = tabManager.tabs.get(1); - const isDark = document.body.className.includes('dark'); - tab.editorView = createEditor(initialEditorContainer, { - content: tab.content, - onChange: (newContent) => { - tab.content = newContent; - tab.isDirty = true; - tabManager.updatePreview(tab.id); - tabManager.updateWordCount(); - tabManager.updateTabBar(); - if (outlinePanelContainer?._refreshOutline) outlinePanelContainer._refreshOutline(); - }, - onUpdate: (view) => { - tabManager.updateCursorPosition(view); - if (outlinePanelContainer?._setActiveHeading) outlinePanelContainer._setActiveHeading(view.state.doc.lineAt(view.state.selection.main.head).number); - }, - isDark, - showLineNumbers: tabManager.showLineNumbers, - }); + const initialTab = tabManager.tabs.get(1); + if (initialTab) { + tabManager.ensureEditor(initialTab); } // Request current theme