m now adds the row under the cursor to a set of marks and steps on, so
mmm picks up three; M takes the whole folder, Esc or :unmark puts it all
back. Marks stay while the list walks, so they can be gathered from
several folders. p, :mv and Shift+digit move the whole set.
With a pointer, Ctrl- or Cmd-click marks a row and Shift-click every row
from the cursor to it. Rows drag onto a folder row, a crumb or a space
pill; a marked row carries every marked node with it.
POST /api/nodes/move takes { ids, parent_id } and moves them all or
none: every node is checked before any moves, sealing into a sealed
folder happens before the one transaction that moves them, and two of a
name get slugs of their own. The single move goes the same way.
$x^2$ inline, $$…$$ for display, and a ```math block, the way GitHub
writes them, in documents, shared pages and .md files alike. KaTeX loads
on first use; until then the math shows as its source. Only the woff2
fonts are bundled.
A file node points at one media row and owns it the way a document owns
what it embeds, so folder deletes, the media browser and exports keep
working. POST /api/nodes/{id}/files streams uploads into a folder;
imports turn non-markdown files into file nodes; exports put them at
their tree path. The browser previews images, video, audio and text,
offers the rest as a download, and takes files dropped on the list.
Migration 0010 widens the kind CHECK by editing the stored schema, as
SQLite documents for loosening a constraint: sqlx runs migrations in a
transaction, where foreign keys cannot be switched off for a rebuild.
- shared view uses the bar, porthole and status band; outline gets its own
window on wide screens; j/k, gg/G, Ctrl-d/u scroll with a vim-style ruler
- rail doors are line icons in groups with hover tooltips and keycaps
- phone: number-only space pills, no nested rims, icon dock, toast messages,
back button and one-line meta in the document header
- keycaps (.kbd) wherever keys are shown, styled scrollbars in Chrome,
outline tracks position on jumps, breakpoints unified at 767px
Adds :today, :next/:prev, :first/:last, :random, :clear, :reload, :copy,
:export, :stats and :theme, plus bangs on :w, :wq and :e. Every command now
declares a group so :help can lay them out under headings.
The help sheet flowed its columns wider than the sheet and clipped the
descriptions; it is newspaper columns now, and it lists the ! variants.
CodeMirror's base theme styles panels for a light editor with selectors the
app stylesheet cannot outrank, so the vim `:` prompt rendered black on black.
Those rules move into the editor's own theme, which does win, and the theme
declares itself dark so the light defaults stop applying at all.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01476ZKdB4k3rPDwvVhXcnDg
CodeMirror injects its own `.cm-cursor` rule after our stylesheet, so the
equally specific override lost and the caret painted black on a dark
background. Qualify the selector, same as `.cm-activeLine`.
`:q!` reached the command table as the literal name `quit!`, which nothing
matched. Commands now carry an optional `bang` variant, and `runCommand`
splits a trailing `!` off any head before looking it up.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01476ZKdB4k3rPDwvVhXcnDg
Mocha with the palette's red as the accent is now the default; the old
green scheme moves to `:set theme=green` alongside amber and ice.
Two readability fixes in the editor:
- The vim block cursor paints the character inside itself in that
character's own syntax colour, so an accent-coloured glyph — a
heading's `#`, a link — vanished against the accent-coloured block.
The glyph is now forced to the background colour.
- CodeMirror injects its own `.cm-activeLine` rule after this stylesheet,
so the equally specific override never applied and the current line
rendered as a bright blue box. Qualified the selector and toned the
band down to a faint tint of the foreground.
Insert mode also gets a 2px bar instead of the browser hairline caret.
Single-user diary served as one Rust binary with the Svelte frontend
embedded.
- axum 0.8 + SQLite (sqlx), migrations run at startup
- stateless HMAC session cookie; credentials from .env, compared in
constant time
- FTS5 full-text search, user input rewritten into quoted prefix terms
- media uploads linked to entries by scanning bodies for /api/media/<id>,
which scopes share-token media access and entry deletion
- unguessable share links (192-bit token) serving a public read-only page
- vim keybindings via CodeMirror plus a modal browse layer and : command
line; disabled on touch devices