awl

Guide

How the pieces fit together.

This page documents how awl's pieces fit together. The command palette (⌘P) already lists every command by name; this page covers the model underneath.


Where your words live

A scratch buffer, always open. Launch awl with no file and you land on a writing surface — no save dialog, no "untitled-1.md". It stashes itself to disk on the same rhythm as everything else: idle, window blur, buffer switch, quit ($XDG_DATA_HOME/awl/scratch.md, or ~/.local/share/awl/scratch.md if XDG_DATA_HOME isn't set — on the web build, localStorage). Relaunch bare and the scratch buffer is where you left it, including parts you never explicitly saved.

Quick notes (⌘N) work the same way, with a home. ⌘N jumps to notes_root (~/notes by default, configurable) and opens a fresh note buffer. Nothing writes to disk until you type something.

Autosave runs on four triggers: idle (about a second after you stop typing), window blur, buffer switch, quit. Writes are atomic (a temp file, then a rename) and never clobber an external edit — if the file changed on disk since awl last touched it, the write is held and a notice appears at the bottom of the screen. Editing again re-arms it. A manual ⌘S always force-writes.

A small dot (•) in the window title marks an unsaved buffer, clearing the instant it's written. The stats HUD (Option-⌘I) shows a SAVED row too — "just now", "3m ago", "unsaved changes."

Local history keeps more than the current text. Every save of a file not under git records a snapshot, pruned by an aged retention ladder: everything from the last ~15 minutes, then one per writing session, then one per day, then one per week — never a flat FIFO cutoff. ⌘⇧H opens the timeline for the current file; Enter on any entry restores it as one ordinary undoable edit. "Keep version" (⌘P) pins a snapshot the retention ladder will never prune. A file under git skips awl's own history entirely — git log is that file's timeline.

A corrupted store never eats your data. Session state, usage stats, recent-projects, the history log, the scratch stash — if any of these is unreadable (garbled, not just missing) when awl tries to load it, the bad file is copied aside first (<name>.corrupt-<timestamp>) before awl falls back to a clean default. Nothing is silently discarded. (config.toml is the one exception — a syntax error there keeps your last-known-good settings and shows a notice, since your editor buffer and undo history already hold your intended text.)

The notes model

A note starts as an ordinary scratch buffer. Save it — or keep typing and let autosave catch up — and awl slugifies the first line into a filename and writes it under notes_root. Change the first line and the file on disk renames to match, until you save it under a different name on purpose.

Three verbs live in the palette once a note exists:

  • Rename note… — pick a new name, breaking the first-line-tracks-filename link.
  • Duplicate note — an immediate copy, no dialog.
  • Move note… — file it elsewhere under (or out of) your notes tree.

None carry a default chord — ⌘P, type "rename", Enter.

Keys

Every command has up to two bindings — slot 1 is native (⌘ on macOS, Ctrl on Linux) and is the one awl teaches; slot 2 is Emacs, a second layer that never goes away. Both fire. The palette (⌘P) shows both next to each command's name.

Linux gets the same commands under Ctrl. Where a native Ctrl chord collides with a bare-control Emacs default (Ctrl-S save vs. Emacs C-s search), the native one wins and the Emacs default steps aside — still one [keys] line away. Set keymap = "emacs" in the config to bring back the whole displaced cluster at once, instead of naming chords one at a time. The Omarchy/Hyprland recipe (that compositor forwards Super+C/X/V as Ctrl+C/X/V for the system clipboard): keymap = "emacs" plus [keys] copy = "C-c", cut = "C-x", paste = "C-v" keeps those three chords native under the emacs preset.

Rebind anything. [keys] in the config maps a command's slugified name to a chord, or up to two. Example — restoring the Option-letter word motions the platform rule retired by default (macOS reserves Option-letters for accented characters):

[keys]
forward_word  = ["M-Right", "M-f"]
backward_word = ["M-Left", "M-b"]

Or capture the key directly: ⌘P → "Keybindings…" opens a picker over every command; Enter starts a capture, and the next key or chord becomes the new binding, written into your config.

The hold-⌘ peek. Hold the arming modifier alone for a beat (⌘ on Mac, Ctrl on Linux) and a card of frequently-used shortcuts appears. Release the hold and the card is gone — no click, no dismiss.

Generated from the live command catalog — never hand-edited (see the law test in src/guide.rs). Every catalog command's resolved default chord, mac glyphs beside Linux words:

CommandmacOSLinux
Go to file…⌘OCtrl+O
Switch project…⌘⇧PCtrl+Shift+P
Recent projects…
Browse files…
Go to heading…
Spell suggestions…⌘;Ctrl+;
Version history…⌘⇧HCtrl+Shift+H
Clean unused assets…
Keep version
Last file⌃TabCtrl+Tab
New note⌘NCtrl+N
Move note…
Rename note…
Duplicate note
Finish file⌘WCtrl+W
Follow linkC-c C-o
Switch theme…⌘TCtrl+T
Caret style…
Dictionary…
Toggle spellcheck
Toggle hidden files⌘⇧.Ctrl+Shift+.
Toggle caret style
Toggle page mode
Toggle writing nits
Widen page
Narrow page
Reset page width
Toggle debug
Toggle outline⌘⇧OCtrl+Shift+O
Toggle typewriter scroll
Toggle menu bar
About
Credits
Guide
Lifetime stats
Line endings…
Align table
Report a Problem
Download file
Check for Updates
Blockquote
Bullet list
Numbered list
Task list⌘⇧LCtrl+Shift+L
Heading
Code block
Bold⌘BCtrl+B
Italic⌘ICtrl+I
Inline code⌘ECtrl+E
Highlight
Strikethrough
Insert link…⌘K
Save⌘SCtrl+S
Quit⌘QCtrl+Q
Search forward⌘F · C-sCtrl+F
Search backward⌘⇧F · C-rCtrl+Shift+F
Find and replace…⌘RCtrl+R
Undo⌘Z · C-/Ctrl+Z · C-/
Redo⌘⇧ZCtrl+Shift+Z
Copy⌘CCtrl+C
Cut⌘X · C-wCtrl+X
Paste⌘V · C-yCtrl+V · C-y
Select all⌘ACtrl+A
Zoom in⌘=Ctrl+=
Zoom out⌘-Ctrl+-
Reset zoom⌘0Ctrl+0
Forward word⌥RightAlt+Right
Backward word⌥LeftAlt+Left
Line start⌘Left · C-aHome
Line end⌘Right · C-eEnd
Document start⌘UpCtrl+Home
Document end⌘DownCtrl+End
Forward charC-f
Backward charC-b
Next lineC-n
Previous lineC-p
Settings…⌘,Ctrl+,
Keybindings…

Looks

Fifteen worlds, one chord away. ⌘T (Ctrl-T on Linux) opens the theme picker — each world pairs its own display face with its own ink ladder. Wagtail is the exception: awl's one monochrome world, drawn in black, white, and nothing between.

Two page widths, one for prose, one for code. The writing column measures 70 characters by default for prose and 100 for code (rustfmt's own convention) — independent settings; widening one never touches the other. Drag the column's edge, or use "Widen page" / "Narrow page" / "Reset page width" in the palette.

WYSIWYG, reveal-on-caret. Markdown markup — a heading's #, **bold**, `code`, ==highlight==, a fenced code block's fence lines — renders concealed except on the line your caret is on, where it shows in full for editing. The file on disk is always plain markdown; only the render is rich. wysiwyg = false disables the conceal entirely.

Reduce Motion is a real accessibility preference, not a cosmetic toggle. Absent config means auto: awl reads the OS-level "Reduce Motion" setting where one is reachable (macOS, the web build) and follows it. Set reduce_motion = true by hand on Linux, where there's no reliable cross-desktop signal yet.

The config file

Settings live in a plain text file, edited inside awl: ⌘P → "Settings" opens config.toml into the buffer (writing the commented starter template first, if none exists). Edit it like any other document, then save — the keymap, folders, and every sticky preference re-apply live, no restart. A config with a syntax error keeps prior values in place and shows a notice.

An absent config is just today's defaults. Once you touch it, it remembers: theme, zoom, page widths, caret style, dictionary, and a dozen other toggles persist across launches the moment you change them live, and every key is hand-editable too.

Awl in the browser

The web build is the same editor compiled to wasm32-unknown-unknown, running in a <canvas> with no native filesystem underneath it.

Desktop (macOS / Linux)Browser
StorageReal files on disklocalStorage, capped around 5 MB — roughly eight to ten novels of plain text; scoped to this browser profile, gone if site data is cleared
Preferences, [keys]~/.config/awl/config.tomlA config.toml over localStorage, same format, persists across reloads
CopyTo the OS clipboardMirrors out to the OS clipboard (best-effort, async)
PasteFrom the OS clipboardFrom awl's own kill ring only — an external copy doesn't appear until you've copied something from awl at least once
Getting a file outAlready on disk"Download file" (⌘P) — saves the active buffer as a plain-text download

Hidden on web: Recent projects…, Version history…, Clean unused assets…, Keep version, Finish file, Lifetime stats, Quit, Check for Updates — daemon, session-restore, and local-version-history machinery with nothing to attach to in a browser tab.

A couple of native chords belong to the browser itself (new tab, new window, and similar). New note and Switch theme… resolve to a working alternate chord on web automatically; every command is also reachable by name through the palette.

The desktop build has no storage cap, real OS clipboard paste, and the commands above — see the project's releases page for macOS and Linux downloads.


Inside the app, press ⌘P and type "Guide" to come back to this page from a buffer, any time.