Skip to content

feat(export): Export as PDF gets a keyboard shortcut (#673) - #679

Merged
PathGao merged 1 commit into
masterfrom
feat/673-export-pdf-shortcut
Aug 18, 2026
Merged

feat(export): Export as PDF gets a keyboard shortcut (#673)#679
PathGao merged 1 commit into
masterfrom
feat/673-export-pdf-shortcut

Conversation

@PathGao

@PathGao PathGao commented Aug 18, 2026

Copy link
Copy Markdown
Collaborator

What this is

Closes #673, asked by @zhouchang3462: Export as PDF was menu-only, which is slow for anyone exporting repeatedly.

Mod+Shift+P now runs it, in reading mode and in edit mode, and the menu item prints the chord beside its label so it is discoverable from where people look today.

Mechanism

Not the Ctrl+Shift+E the request suggested — Inline Code has held that chord since the formatting shortcuts went in, and the editor toolbar prints it, so taking it would break a documented binding to add a new one. P is the print mnemonic every desktop app shares, and Markpad's unshifted Mod+P is the command palette (where Obsidian also puts it), so the shifted spelling is both free and the nearest thing to Print. No other entry claims it on any platform, which shortcutRegistry.test.ts checks.

The chord is bound in both keyboard layers, because they are genuinely separate: outside the editor, viewerKeymap.ts maps the keystroke to an export-pdf command the viewer dispatches; inside it, Monaco resolves its own keybindings first and calls stopPropagation, so an editor.addAction entry is what makes the chord work in edit mode. Registering only one leaves it dead in the other mode.

The empty-document gate ended up mattering more than expected. The menu hides both Export items when there is nothing to export, and the first version of this repeated that condition at the chord's dispatch. Measured with the chord actually pressed, that guard held in reading mode and did nothing in edit mode — the editor's action calls the export function directly, one layer below the dispatcher. So the condition now lives at the top of exportAsPdf itself, and is the exported hasExportableDocument the menu gate also switched to, rather than a third spelling of it.

Measured by pressing the chord and watching the Tauri commands the frontend issues:

document mode commands
empty untitled buffer edit (none)
# Export me edit render_markdown, print_pdf
# Export me reading print_pdf

render_markdown appears only in edit mode because the export refreshes a preview that may be stale — the pre-existing syncPreviewForPrint step, unchanged here.

Scope

Export as HTML keeps its menu-only route. The request was about PDF, the registry makes a second entry a few lines, and picking a chord for it is a decision nobody has asked for yet.

No new setting: the chord is fixed, like every other one in the app. If rebindable shortcuts arrive, this entry travels with the rest.

Tests

No new test file. shortcutRegistry.test.ts already holds this shape and covers the entry as soon as it exists — changing the registry's chord to something unbound turns three of its assertions red (every chord the registry advertises is the chord the editor really registers, …runs the command it names, outside the editor, every chord the document handler answers is advertised). Checked by doing it.

renderedHtmlField.spec.ts needed one line: it parses the export menu's {#if} out of TitleBar.svelte and evaluates it against a supplied environment, so the helper the gate now calls has to be supplied. It is passed the real function, so what that suite evaluates is still the shipped decision.

Verification

npm audit             0 vulnerabilities
npm run check         800 files, 0 errors, 0 warnings
npm test              922 pass, 0 fail
npm run test:vitest   41 files, 365 pass
cargo test            148 pass

The behaviour table above was measured in Chromium against the dev server, with window.__TAURI_INTERNALS__ stubbed so the frontend boots outside Tauri and every invoke is recorded. That proves dispatch and gating; it does not prove the PDF itself, since print_pdf is answered by Rust — the export path underneath is unchanged and already covered by editorPdfExport.test.ts and exportFoldParity.test.ts.

Not verified: Windows and Linux. The chord is platform-independent here (Mod resolves per platform, and no branch is OS-specific), but nobody has pressed it there.

Mod+Shift+P, bound in both keyboard layers — the document handler and
the editor's own action table — so it works in reading and edit mode.
The menu item now prints the chord beside its label.

Not the Mod+Shift+E the request suggested: Inline Code has held that
since the formatting chords went in. P is the print mnemonic, and the
unshifted Mod+P is already the command palette.

The menu hides Export for a document with nothing in it; that condition
becomes `hasExportableDocument` so the chord is gated by the same one
rather than a second copy of it.
@PathGao
PathGao merged commit 790271c into master Aug 18, 2026
4 checks passed
@PathGao
PathGao deleted the feat/673-export-pdf-shortcut branch August 18, 2026 14:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] Add keyboard shortcut for exporting to PDF

1 participant