Notable changes to keynot, newest first. The format follows Keep a Changelog; versions follow semantic versioning.
0.5.0 - 2026-07-10
- Press
sduring a show to peek at the current slide's speaker notes in an overlay; any key closes it.
- Code windows lost their traffic-light dots: just the rounded frame and the language label now.
- An emoji shortcode at the start of a line (
:crab: A Ferris Talk) no longer parses as definition-list syntax, which ate the colon, bolded the previous line as a "term", and indented the text. Known shortcodes at line starts are now replaced before markdown parsing; code fences and unknown names are untouched.
0.4.0 - 2026-07-08
- Dynamic shell completions: register once (one line, or a drop-in
completion file for fish/bash) and
keynot pl<TAB>completes from the live CLI -- subcommands, flags, and values. - Press
eduring a show to open the deck in$VISUAL/$EDITORat the line you are looking at (the highlighted block, or the top of the scrolled view); exiting the editor reloads from disk and resumes where you were. Knows the line-jump syntax for the vi/emacs family, VS Code, Sublime, and TextMate; falls back tovi(notepadon Windows). - GFM tables render with rounded borders, bold headers, and per-column alignment; columns size to their content and word-wrap when the table is wider than the slide.
- GFM alerts (
> [!NOTE]and friends) render a colored, labeled bar with an upright body; plain quotes stay italic. - Footnotes:
[^1]references become accent markers, with the notes collected at the end of their slide or column. - Definition lists render bold terms with indented definitions.
- Heading attributes (
{#id}) parse and no longer show as literal braces. - Emoji shortcodes:
:crab:and friends (GitHub's names) become real emoji in prose; unknown names and anything in code stay literal. keynot --helplinks to the crate page.- Overflowing slides scroll: on a slide taller than the terminal, walking the line highlight (down/up) moves the view to follow the bar, with dim markers showing how many lines are hidden past each edge. Esc (or changing slides) returns to the top.
keynot checkreports the tallest slide and its height at a reference 80 columns; run in a terminal, it also says whether every slide fits that terminal's real size.
0.3.0 - 2026-07-08
- Background gradients:
colors.backgroundaccepts{ gradient: ['#hex', ...], direction: vertical | horizontal | radial }in addition to a solid color. The dark theme's default background is now a slate gradient (#2d2d30down to#181818). - Code blocks render as small terminal windows: a rounded border with
traffic-light dots, the language name in the bottom edge, and a panel
darker than any background.
code_style: plainrestores the bare panel; the frame color is themeable ascolors.code_border. - The speaker line highlight is column-aware: down/up walk lines within a column, left/right move between columns, and moving past the slide's edge changes slides (so single-column decks behave exactly as before).
keynot checkerrors on unknown frontmatter keys, listing each with its line number and the valid keys;keynot playignores them so a deck written for a newer keynot still opens on an older one.- Error reports are colorized on a terminal (respecting
NO_COLOR); piped output stays plain. - FORMAT.md documents every frontmatter default, enforced by tests that fail when the docs drift from the code.
- A set-but-empty
VISUALno longer shadows a validEDITORwhen resolving theekey's editor. - Editor commands with quoted arguments or spaces in the program path now parse shell-style.
-
Usage documentation (subcommands, keys, player behavior) moved from FORMAT.md to a new USAGE.md; FORMAT.md is now strictly about the file format.
-
The dark theme's code panel darkened to
#141414so it stands out against the gradient background.
- Frames draw inside synchronized-output escapes (mode 2026), so transitions cannot tear in terminals that support it (kitty, Ghostty, WezTerm, and friends); others ignore the escapes.
- The sweep transition's direction flipped to match the push: moving forward, new content arrives from the right.
- Transitions animate the whole screen instead of only the slide text's rows, which made the push and sweep effects look like a broken middle band.
- Transitions no longer skip randomly: the idle loop's wake interval (up to 500ms) was charged to a new transition's first frame, which often exceeded the whole animation. Advancing a slide now restarts the animation clock.
- Reloading with
rno longer freezes the show while URL images re-fetch; decodes happen on a worker thread and the network is never touched from the draw path. - A highlight begun during a slide transition no longer lands on an arbitrary line of the incoming slide.
0.2.0 - 2026-07-08
- Multi-column slides:
|||on its own line splits a slide into side-by-side columns (fence-aware, like---). play --images auto|halfblocks|offto control how pictures draw; half-blocks survive asciinema recordings.KEYNOT_LOGwrites tracing diagnostics (graphics probe, image fetches, render timings) tokeynot.log.
- The default slide transition is
coalesce(was theslidepush). - The tour slimmed to five slides that showcase columns throughout.
- Images in a column draw inside their column instead of centering across the whole slide.
- kitty-protocol images no longer vanish when a transition effect overwrites the cell carrying the image transmission.
0.1.0 - 2026-07-08
Initial release: markdown slides with YAML frontmatter, marp-style
--- separators, and speaker-note comments; VS Code Dark+ and light
themes with per-color overrides; syntax-highlighted code; images via
kitty/iTerm2/sixel/half-blocks, from files or URLs; slide transitions;
a speaker line highlight; an outline view with number jumping; a shell
escape; and live reload.