Guide
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.
The first launch opens a document, not an empty
editor. With nothing to resume and no configured writing
folder, awl opens its authored Welcome through the recoverable scratch
store. It does not create ~/notes or place a file in a
user folder. Its edits survive relaunch.
The first new document asks for a writing folder, then opens the ordinary unnamed document there. Keep tutorial… uses the same folder choice and saves the edited Welcome as Markdown.
| Where it lives first | awl's recoverable scratch store, not a user folder |
| Configured folder | default_folder is intentional: Welcome is an ordinary welcome.md there |
| Shown again? | No. awl records the fact once, in $XDG_DATA_HOME/awl/welcomed (or ~/.local/share/awl/welcomed) |
| To be welcomed again | Delete that marker file and the scratch document, then launch with nothing to resume |
| In the browser | The same document is seeded into the tab's storage on a first load, alongside tour.md, prose.md and japanese.md |
The chords the document teaches are substituted into it as it is written, from the same command catalog the palette reads, so it names your platform's own bindings rather than a hand-typed guess.
A scratch buffer, always open. After that first
launch, 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.
A fresh document (⌘N) works the same way, in the folder
you're already in. ⌘N opens a new, unnamed document in the
active folder — wherever you last opened a file or switched
projects, never a separate jump. Nothing writes to disk until you
type something. An explicitly configured default_folder
is used as that initial folder; otherwise awl asks before the first
real file is created.
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.
Nothing awl writes ever replaces a change made outside it. awl remembers the exact bytes it last saw in each open file, so a rewrite that keeps the same timestamp and the same length is still noticed. It re-checks when you return to the window, when you switch or open a file, and before every write.
| what awl finds | what happens |
|---|---|
| the file is unchanged | the write goes through |
| the file changed, and you have no unsaved edits | awl reloads it, keeping your cursor and scroll |
| the file changed and you have unsaved edits | both are kept — see below |
When both changed, you choose. awl keeps your
text as the one document you are editing and stops writing to the
file, so neither version can be lost. A changed elsewhere
line sits beside the filename in the page margin for as long as the
change is unresolved, and your unsaved text is copied to awl's own
data folder — so it survives a crash, and comes back when you reopen
the file. Three commands settle it:
| command | what it does |
|---|---|
| Review the change | shows both versions, one at a time, changing nothing |
| Save your version | re-checks the file, then writes your text over it |
| Use disk version | replaces your text with the file's, as one edit ⌘Z takes back |
Review the change opens a reading surface with three views — Differences, Your version, and Version on disk — and Esc returns you to editing with nothing settled. It is a read: neither version changes until you run one of the other two.
Saving, switching files, renaming, moving and Finish file all wait until you have chosen. ⌘S does not force-write over an external change; Save your version is the explicit way to keep yours.
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.)
A fresh document (⌘N) starts unnamed, like the scratch buffer. Save it — or keep typing and let autosave catch up — and awl slugifies the first line into a filename and writes it in the active folder, ONCE. Changing the first line afterward never renames the file again; it's an ordinary document from that first save on, exactly like one you opened from disk.
Three generic file verbs live in the palette for any document:
None carry a default chord — ⌘P, type "rename", Enter.
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.
The pointer gets a bounded bridge. Select text
with the mouse in a Markdown buffer — drag, double-click a word,
triple-click a line — and a small row of buttons appears beside the
selection: bold, italic, highlight, code, strikethrough, heading,
link. Each one fires the same command its chord does, and lights up
when the selection already carries that format. Any key press, or
losing the selection, dismisses it. A keyboard selection never
summons it, and it never becomes a persistent toolbar.
popover = false turns it off, and the settings row that
does the same is "Format popover".
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:
| Command | macOS | Linux |
|---|---|---|
| Go to… | ⌘O | Ctrl+O |
| Open file… | ||
| Open folder… | ||
| Spell suggestions… | ⌘; | Ctrl+; |
| Version history… | ⌘⇧H | Ctrl+Shift+H |
| Compare with version… | ||
| Clean unused assets… | ||
| Keep version… | ||
| Last file | ⌃Tab | Ctrl+Tab |
| New document | ⌘N | Ctrl+N |
| Keep tutorial… | ||
| Move… | ||
| Rename note… | ||
| Duplicate note | ||
| Finish file | ⌘W | Ctrl+W |
| Follow link | C-c C-o | |
| Switch theme… | ⌘T | Ctrl+T |
| Caret style… | ||
| Dictionary… | ||
| Toggle spellcheck | ||
| Toggle caret style | ||
| Toggle page mode | ||
| Toggle writing nits | ||
| Widen page | ||
| Narrow page | ||
| Reset page width | ||
| Toggle debug | ||
| Toggle outline | ⌘⇧O | Ctrl+Shift+O |
| Fold section | ⌘⇧E · C-c C-f | Ctrl+Shift+E |
| Collapse other sections | ⌘⇧M · C-c C-t | Ctrl+Shift+M |
| Toggle typewriter scroll | ||
| Toggle menu bar | ||
| About | ||
| Credits | ||
| Lifetime stats | ||
| Writing streaks | ||
| Line endings… | ||
| Align table | ||
| Tag document language | ||
| Insert Date | ⌘⇧D · C-c . | Ctrl+Shift+D |
| Report a Problem | ||
| Download file | ||
| Check for Updates | ||
| Blockquote | ||
| Bullet list | ||
| Numbered list | ||
| Task list | ⌘⇧L | Ctrl+Shift+L |
| Heading | ||
| Cycle heading | ||
| Code block | ||
| Bold | ⌘B | Ctrl+B |
| Italic | ⌘I | Ctrl+I |
| Inline code | ⌘E | Ctrl+E |
| Highlight | ||
| Strikethrough | ||
| Export as Word… | ||
| Export as HTML… | ||
| Export as PDF… | ||
| Insert link… | ⌘K | |
| Save | ⌘S | Ctrl+S |
| Quit | ⌘Q | Ctrl+Q |
| Search forward | ⌘F · C-s | Ctrl+F |
| Search backward | ⌘⇧F · C-r | Ctrl+Shift+F |
| Find and replace… | ⌘R | Ctrl+R |
| Undo | ⌘Z · C-/ | Ctrl+Z · C-/ |
| Redo | ⌘⇧Z | Ctrl+Shift+Z |
| Copy | ⌘C | Ctrl+C |
| Cut | ⌘X · C-w | Ctrl+X |
| Paste | ⌘V · C-y | Ctrl+V · C-y |
| Select all | ⌘A | Ctrl+A |
| Zoom in | ⌘= | Ctrl+= |
| Zoom out | ⌘- | Ctrl+- |
| Reset zoom | ⌘0 | Ctrl+0 |
| Forward word | ⌥Right | Alt+Right |
| Backward word | ⌥Left | Alt+Left |
| Line start | ⌘Left · C-a | Home |
| Line end | ⌘Right · C-e | End |
| Document start | ⌘Up | Ctrl+Home |
| Document end | ⌘Down | Ctrl+End |
| Forward char | C-f | |
| Backward char | C-b | |
| Next line | C-n | |
| Previous line | C-p | |
| Delete word forward | ||
| Delete word backward | ||
| Settings… | ⌘, | Ctrl+, |
| Keybindings… |
20 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, revealed by caret or selection. Markdown
markup — a
heading's #, **bold**,
`code`, ==highlight==,
~~strikethrough~~, a fenced code
block's fence lines — renders concealed except on the line your
caret is on, or any line your selection touches, where it shows in
full for editing. A fenced block reveals whole: its fence lines show
while the caret sits anywhere inside it. 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.
"Settings…" is a summoned workspace, not an overlay. It takes the viewport: a category rail — All, Editor, Appearance, Writing, Files, Keybindings, Advanced — beside the rows it governs. Up/Down moves the category, Enter or Right transfers focus into the settings, Left comes back to the rail — except on a row whose value is a slider, where Left and Right adjust it and the footer says so — Backspace on an empty search field comes back as well, Tab moves focus between the two either way, and Esc leaves for the editor from wherever you are — exactly where you left it. On a window too narrow to hold both, the workspace shows one region at a time and the same keys move between them. Every change applies live; a sticky one is written to the config in the same step.
The settings are a plain text file, and you can edit it
directly. The Advanced category's "Edit config as text" row
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.
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 | |
|---|---|---|
| Storage | Real files on disk | localStorage, 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.toml | A config.toml over localStorage, same format, persists across reloads |
| Copy | To the OS clipboard | Mirrors out to the OS clipboard (best-effort, async) |
| Paste | From the OS clipboard | From 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 out | Already on disk | "Download file" (⌘P) — saves the active buffer as a plain-text download |
Hidden on web: Version history…, Compare with version…, Clean unused assets…, Keep version…, Finish file, Lifetime stats, Writing streaks, 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 document 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. The releases page carries the Linux x86_64 download; macOS builds from source until a signed build is ready.