github ZenNotes/zennotes v2.15.0
ZenNotes 2.15.0

6 hours ago

ZenNotes 2.15.0

Installers for macOS, Windows, and Linux (x64 + arm64) are attached below.

✨ Features

  • A whole note can be a task now, not just a checkbox. Tag a note's frontmatter with task (tags: [task]) and the note itself becomes a task, with its status, priority (high / normal / low), due, scheduled, and tags living in frontmatter while the body holds free-form detail. These "task files" show up in the Tasks List, Calendar, and Kanban right alongside the inline - [ ] checkboxes you already use, so both styles live in one vault. It follows the TaskNotes convention, so your vault stays interoperable with TaskForge and Obsidian. Quick-add one from the command palette (New Task, or New Task in Folder… to choose where it lands), the + New task button in the Tasks header, the a key in Vim mode, or the :newtask / :task command — and :newtask Projects/Website drops it straight into a folder so multiple projects stay organized. New task files default to your configured tasks location (Settings → New Drawings, Databases & Tasks; the inbox by default), and the folder-picking options override that per task. Checking a task file off rewrites its frontmatter (status: done plus a completedDate) instead of a checkbox character, rescheduling from the calendar or moving its Kanban column updates the matching frontmatter field, and deleting one trashes the note. Frontmatter also reads more clearly across the app: property values now render at full text brightness with the keys as muted labels, so an all-frontmatter note like a task file no longer fades into the background.

  • Turn a URL into a rich embed or bookmark, Notion-style. Drop a link onto an empty line (or use the Embed / Bookmark slash commands) and a small Paste as menu offers three choices: Embed a curated player (YouTube or Vimeo) in a sandboxed inline frame, a Bookmark card built from the page's title, description, thumbnail, and favicon, or keep it as a plain URL. Both render live in the editor and the reading view: the video plays inline, the card opens its link in your browser on click, and a hover Edit pill (or stepping in with j/k) reveals the source to change the URL. The paste menu is fully keyboard-driven, in keeping with the rest of the app: j/k or arrows move the highlight, Enter picks, Esc dismisses, and it appears for both Cmd/Ctrl+V and Vim's p/P. Bookmark metadata is fetched by the desktop app with private-network and size guards; the web build falls back to a bare link card.

  • Choose your math typesetter: KaTeX or Typst. A new Settings ▸ Editor ▸ Math renderer option lets you render $…$ and $$…$$ math with Typst instead of the default KaTeX. Typst reads the blocks as Typst markup rather than LaTeX (so $ integral_0^1 x^2 dif x = 1/3 $ and $ mat(1, 2; 3, 4) $ render), and each note's math is written for whichever engine you pick. It applies in both the live editor and the reading view, block equations get the same paper-tinted card as KaTeX, and clicking a rendered block opens it for editing. The whole Typst toolchain is bundled and runs fully offline: the compiler, the renderer, and the New Computer Modern fonts ship with the app, so nothing is fetched from the network, and the output matches the classic Computer Modern look. KaTeX stays the default, so existing notes are untouched. (#428, requested by @satwikShresth)

  • Relaxed $$ math delimiters, LaTeX-style. A new Settings ▸ Editor ▸ Writing ▸ "Relaxed $$ math delimiters" toggle (off by default) lets a $$…$$ display block render even when prose sits before the opening fence (The Gaussian integral: $$…) or after the closing fence ($$… — the Basel problem.), instead of requiring the $$ to sit alone on its line. The surrounding text moves to its own paragraph in the reading view. It stays opt-in because a bare $$ legitimately shows up in prose (prices, shell variables), so existing notes parse exactly as before until you turn it on. Reading view only for now; the live editor still shows the raw source for those shapes. (#434, requested by @Mitchman05)

  • Markdown links can point at files outside your vault. A link like [my script](~/.local/bin/build.sh) used to offer to create a note (~/.local/bin/build.sh.md); now it opens the file with your system's default app instead, after a quick confirmation. Works from the editor and the reading view, for ~/…, file://…, and absolute paths. Vault notes, assets, and relative links are unchanged, and it is desktop-only (the web build has no filesystem access). (#424, requested by @cyperion)

  • The status bar previews a link's target on hover. Move the pointer over any link (a Markdown link, an external file path, a URL, or a [[wikilink]]) and its destination shows on the left of the status bar, browser-style, in both the editor and the reading view.

  • Type to filter the table's action menu. Open a WYSIWYG table cell's action menu (with m or right-click) and just start typing: the menu narrows to the items whose label matches your query, case-insensitive, with the match highlighted and a small header showing the query and how many items are left. Backspace widens it, Escape clears the filter before closing, Enter runs the highlighted match, and j/k still move within the results. It mirrors the sidebar context menu, so del jumps straight to the Delete actions. (#438, requested by @uNyanda)

  • Nested tags, shown as a collapsible tree. Tags that share a /-separated prefix (like #project/compiler and #project/website) now group into a collapsible tree in both the sidebar Tags section and the Tags view, instead of a flat list. An ancestor that isn't itself a tag (project, when only #project/compiler exists) becomes a grouping row with a rolled-up count. Nothing changed about how tags parse or filter: #project/compiler was always a single tag, this is purely how the list is grouped for browsing. The sidebar renders tags as indented chips (real tags filled with #, grouping nodes a fainter chip) so they still read as tags rather than file rows; a disclosure triangle expands and collapses, clicking a leaf filters by it, and j/k/l/h navigate the tree from the keyboard. Expand and collapse state is shared between the two surfaces and persists across restarts. It sits behind a new Settings ▸ Appearance ▸ Chrome ▸ "Nested tags (tree view)" toggle (default on); turn it off for the flat list of full tag names, and a vault with no nested tags renders as a flat tree either way. (#439, requested by @uNyanda)

🐛 Fixes

  • You can type a backtick again in the editor on macOS AltGr-style keyboard layouts. With a custom layout whose Option layer emits characters directly (common for Czech, Polish, German, and other ISO-layout users), the Option combo that produces ` inserted nothing in the editor, while working everywhere else. The stock CodeMirror completion keymap binds mac-only Alt-` (and Alt-i) to "open completion", which swallowed the keystroke. Those two bindings are now removed, so the characters type normally; Ctrl-Space still opens completion. Fixed across the main editor, Quick Capture, the template editor, and the reference pane. (#429, diagnosed by @vlcinsky)

  • Vim f/F/t/T can now find [ and ]. Pressing one of the find-character motions and then [ or ] did nothing: the cursor stayed put, Vim stayed in "find" mode, and your next keystroke jumped to that character instead. The brackets were being intercepted by the [b/]b (previous/next buffer) shortcuts before Vim could take them as the search target. Those shortcuts (and gt/gT) now stand down while Vim is mid-command, so f[, t], r[, and friends work as expected. (reported by Julie on Discord)

  • Vim f/t/r now work inside WYSIWYG table cells too. In Vim mode, a table cell runs its own small modal editor (it's a rendered cell, not the main editor), and it had never implemented the find-character motions or replace-character: pressing f, t, F, T, or plain r in a cell in Normal mode did nothing. They're now implemented directly in the cell editor — f/F/t/T find a character, r replaces the one under the cursor, and ;/, repeat the last find — matching how they behave in the regular editor. (#435, reported by @uNyanda)

  • Frontmatter no longer renders as a giant heading in the editor. When a frontmatter block's last line sat right against the closing --- (no blank line in between), the markdown parser tokenized it as a setext heading, so valid frontmatter showed with large heading typography in edit mode. Frontmatter now always renders as the compact metadata card it's meant to be, regardless of spacing before the closing fence. (#426, thanks to @junereycasuga)

  • Vim j/k can no longer get stuck when word wrap is on. The display-line j/k motion (which steps through soft-wrapped rows) is pixel-based, and on some setups — notably compositors using fractional display scaling — the underlying coordinate lookups can be imprecise enough that the motion fails to advance across a wrap boundary, leaving the cursor stuck even with lines still that way. j/k now fall back to a logical-line step whenever the display-line move doesn't make progress, so the cursor always keeps moving. On setups where the pixel motion is accurate this changes nothing. (#423, reported by @uNyanda)

  • Note tab titles no longer get clipped in Compact layout density. With Layout density set to Compact and Wrap note tabs off, the horizontal scrollbar under the tab bar was rendering much thicker than intended and slicing off the bottom of the tab titles. Two things were wrong: a stray scrollbar-color style quietly disabled the slim 6px scrollbar the tab bar was supposed to use (so it fell back to a chunky ~15px one), and each tab was pinned to the full bar height, so it overflowed the space the scrollbar left. The tab bar now uses its intended slim scrollbar and the tabs size to fit above it, so titles stay fully visible and centred at every density. (#421, reported by @uNyanda)

  • The editor no longer jitters while typing with a Scroll offset set. With Editor → Scroll offset greater than 0, the viewport repositioned to keep the configured margin above and below the cursor by way of a scroll that landed a frame after each keystroke, so continuous typing made the viewport visibly jitter (worst in split panes and short windows; Zen mode or a Scroll offset of 0 avoided it). The repositioning now happens in the same frame as the keystroke with no extra editor transaction, so it tracks the cursor smoothly. As a bonus, a large Scroll offset in a short editor no longer fights itself: the margin is capped at half the visible height and the cursor stays centred instead of jamming against the top edge. (#420, reported by @uNyanda)

  • The Visual-mode format bar no longer advertises Ctrl+I for Italic where that chord can't apply it. On Linux and Windows Ctrl+I is the Vim jumplist's "go forward" in normal and visual mode (it took priority in v2.13.2), so the selection format bubble showing Ctrl+I next to Italic was misleading: pressing it jumped forward in your note history instead of italicizing. The Italic shortcut hint is now hidden in that exact context (Vim on, Linux/Windows, not in insert mode), so the displayed key and the actual behaviour match. Italic is unchanged everywhere it already worked: one click or Enter in the bar itself, Ctrl+I in insert mode, and Cmd+I on macOS, where there is no collision. (#419, reported by @uNyanda)

  • Creating a note from a template now lands keyboard focus in the editor. Making a note from a template via the Leader menu (Leader t), the command palette, or :template opened the note but left focus on the picker/prompt that just closed, so typing did nothing until you clicked into the editor. The template flow now restores editor focus on create, the same way the daily/weekly/monthly note commands already do, so you can start typing immediately. (#436, reported by @uNyanda)

  • Keyboard focus works around the WYSIWYG table context menu. Opening a table cell's action menu (with m or right-click) and driving it from the keyboard was broken two ways. While the menu was open, j/k/Enter leaked past it to the sidebar: the note-list navigation handler runs on window capture from app startup, ahead of the menu's own handler, and the table menu never marked itself as a context menu the way every other overlay does. And after a no-target action (Delete row/column, Sort column), the table re-rendered with nothing focused, so focus fell to the page body and typing did nothing. The menu now marks itself so the global handlers stand down while it is open, and no-target actions return focus to the editor once they complete. So m opens the menu, j/k move the highlight, Enter runs the action, Esc closes it, and you can keep typing right afterward. (#437, reported by @uNyanda)

  • Task wikilinks render consistently across every task surface. A task like - [ ] Complete [[Project Spec]] review rendered its [[wikilink]] as styled text in the Tasks-view calendar, the task list, and the Kanban, but showed the raw [[ ]] brackets in the Space+C calendar panel and on the home/landing view. Those two surfaces printed the task text as a plain string; they now run it through the same inline renderer as everywhere else, so wikilinks (and other inline markdown) show as styled text no matter where a task appears. (#440, reported by @uNyanda)


Keyboard-first and local-first, as always.

Don't miss a new zennotes release

NewReleases is sending notifications on new releases.