Files
narl-workspace/docs/wiki/Commands.md
T
nvrl 0eabcb2333 keys: one table drives dispatch, help, footers, the rail and the wiki
keymap.ts lists every key with its context, action and help line.
actions.ts holds what each one does, typed against the table so a key
without an action, or an action without a key, does not compile.
modes.ts stacks the contexts (always > sheet > drawer > workspace >
writing > focused tile > special > global) and writes the two-key
pending logic once. App.svelte's 480-line onkeydown is now one call.

Help, the panel footers (a shared Keys component), the rail's keycaps
and Commands.md all read the table; the wiki gains the card and
scratchpad key tables.

One fix on the way: Ctrl-S in the editor no longer saves twice, which
could make the second save fail as "changed somewhere else".
2026-10-22 03:42:19 +02:00

263 lines
15 KiB
Markdown

<!-- Generated by scripts/wiki.ts from web/src/lib/keymap.ts and web/src/lib/commands.ts. Edit that, then run `make wiki`. -->
# Keys and commands
Everything here is also on `?` (`:help`) inside the app, which draws the same
lists. Keys act on whatever has focus: the row under the cursor in the list, or
the document in the focused tile. Inside the editor the full vim keymap is live,
and `:` opens the command line, where `Tab` completes commands and their
arguments and `↑` / `↓` recall earlier lines.
## Keys
### Browsing and reading
| key | what it does |
| --- | --- |
| `1 … 9 · 0` | switch to that space, like a workspace |
| `Shift 1 … 9` | send the marked nodes, or the selected one, to that space |
| `Tab · Shift-Tab` | next / previous space |
| `w` | overview of every space — hjkl, then Enter |
| `f` | fullscreen the focused pane or tile; again or Esc to leave |
| `Alt-h/j/k/l` | focus the tile that way, from the editor too — left of the leftmost is the list |
| `Alt-Shift-h/j/k/l` | move the focused tile that way |
| `L · Shift-Enter` | open the row in a new tile beside the others |
| `gt / gT` | next / previous tile — in the editor too |
| `Alt-q` | close the focused tile — :close; :only closes the others |
| `j / k · ↓ ↑` | move down / up the list — scroll the document when it has focus |
| `gg / G` | first / last row, or top / bottom of the document — a first g, d, ] or [ waits a second in the status line |
| `Ctrl-D / Ctrl-U` | half a page down / up the open document |
| `zl / zh · zL / zH` | the wide table or code block at the top of the view, sideways — a little, or half its width |
| `]] / \[\[` | next / previous heading of the document — in the editor too |
| `gO` | the headings as a list: j/k, Enter jumps there |
| `F` | hints over the links and buttons in view — type one to follow it |
| `gf / gx` | in the editor: follow the link under the cursor / open it in a tab |
| `gx` | open the file under the cursor in a tab of its own |
| `Enter · l` | open a document, or enter a folder — on an open keystore or sealed file, Enter asks for its password |
| `h` | from the document to the list, from the list up a level |
| `o` | new document here, straight into insert mode |
| `O` | new folder here |
| `i · a` | edit the open document |
| `R` | rename what is under the cursor — document, folder or card — starting from its name |
| `m / p` | pick nodes up, then drop them all into the folder you walk to |
| `M` | pick up the whole folder — again puts it all back |
| `Ctrl / Shift-click` | pick a row up · every row up to it — drag them onto a folder |
| `S` | the special workspace: the board, the agenda and the calendar side by side — S again, q or Esc leave it |
| `Tab · Alt-h/j/k/l` | in the special workspace: the next tile, or the one that way — l past the last list and j past the agenda go on too |
| `t` | agenda — late, due this week, in hand, on every board — in the special workspace |
| `T` | today's diary entry, started if there is none — from templates/day when the diary has one |
| `C` | the diary by month, in the special workspace: h/l a day, j/k a week, H/L a month, . today, Enter opens or starts the day |
| `[d / ]d` | the diary entry before / after the one open, by date |
| `Ctrl-P` | find anything, in every space — Enter opens the result lit beside them, n goes on |
| `b` | the board, in the special workspace: this space's, or the last one shown — 1 … 9 there shows another's |
| `c` | capture a card into this space's inbox, without leaving here |
| `Esc · q` | close the document, and its tile when there are several |
| `/` | full-text search, inside the current space and its text files — Tab or Ctrl-N/P walk the results, Enter opens one |
| `n / N` | next / previous search result, opened beside the results — :noh clears the search |
| `s` | toggle sharing for the document — asks before taking it back |
| `y` | mint a new share link and copy it — asks, the old one stops working |
| `x · dd` | delete what has focus — the row in the list, the document in its pane — into the trash (asks y/N) |
| `u` | undo the last delete: it comes back out of the trash — :trash has the rest |
| `gh` | the open document's earlier versions, as diffs — Enter brings one back |
| `gb` | the documents that link to the open one — \[\[title]] links by title, \[\[ completes one while writing |
| `:` | command line — Tab / Shift-Tab cycle the matches, then the argument; ↑ ↓ recall what ran before |
| `Ctrl-S` | save, from anywhere |
| `?` | this screen, from the editor too — h/l a column, / filters it down |
### On a board
The first list is the inbox, the last list is done.
| key | what it does |
| --- | --- |
| `h / l` | to the list left / right — right of the last is the agenda |
| `j / k` | down / up the cards |
| `gg / G` | first / last card of the list |
| `J / K` | move the card down / up its list |
| `H / L` | move the card to the list left / right |
| `Space` | into the done list, or back out to the inbox |
| `Enter` | turn the card over: its labels, description and checklist |
| `gf` | the card's notes — a document, made on first use; q comes back |
| `o · c` | new card on this list |
| `D` | due date: fri, tm, +3d, 10-31 … |
| `R` | rename the card, or the list when it is empty |
| `z` | show done cards older than a week |
| `F` | a letter over every card in view — type it to put the cursor there |
| `r` | read the board again, for changes made elsewhere |
| `x · dd` | delete the card (asks y/N) |
| `q · Esc` | leave the special workspace |
### On the back of a card
| key | what it does |
| --- | --- |
| `j / k` | down / up the checklist |
| `gg / G` | first / last step |
| `Space · x` | tick the step, or untick it |
| `o` | a new step below the cursor — :task on the line |
| `r` | reword the step |
| `J / K` | move the step down / up |
| `dd` | drop the step |
| `e · i · Enter` | write the description, in the editor — :w writes it, :q or Esc in normal mode leaves |
| `a` | put on a label, or take it off — :label on the line, Tab offers the board's |
| `R · D` | rename the card, its due date |
| `H / L` | send the card to the list left / right |
| `gf` | the card's notes — a document, made on first use; q comes back |
| `q · Esc` | back to the board |
### In the agenda
| key | what it does |
| --- | --- |
| `j / k` | down / up the cards, then what was written on this day in earlier years, then into the calendar |
| `h` | to the board |
| `Enter` | to the card, on its own board beside — or to the entry |
| `Space` | done, where it stands |
| `D` | due date: fri, tm, +3d … — :due on the line |
| `:` | the line, with the agenda kept up — :repeat weekly acts on the card |
| `H / L` | to the list left / right on its board |
| `T` | today's diary entry |
| `q · Esc` | leave the special workspace — a document opened from it comes back here on q |
### In the scratchpad
| key | what it does |
| --- | --- |
| `Q` | lower the scratchpad over whatever is on screen, or raise it again — :scratch <text> takes a note without it |
| `j / k` | down / up the notes, the one touched last on top |
| `o` | a new note, written straight away — it saves itself |
| `Enter · e · i` | write the note — Esc in normal mode, or :q, comes back to the notes |
| `K` | keep the note: a document in the folder being browsed, titled by its first line — :keep <title> names it |
| `dd` | drop the note (asks y/N) |
| `q · Esc · Q` | raise the scratchpad |
## Commands
A command takes a `!` for its forcing variant where one exists, the way vim's
do: `:w!`, `:space! <name>`, `:import!`.
### Spaces & folders
| command | what it does |
| --- | --- |
| `:space, :sp [name]` | switch to a space, or list them |
| `:space!` | create a space with that name and switch to it |
| `:mkdir <name>` | make a folder here |
| `:cd <name\|..\|/>` | enter a folder, .. goes up, / back to the space |
| `:import, :imp` | upload a folder into this one — markdown becomes documents, links follow |
| `:import!` | import loose files, or a .zip of a folder; :import! / pours an :export! back in, spaces and boards and all |
| `:move, :mv <folder\|..\|/>` | move the marked nodes, or else the selected one, into a folder here, up one level, or to the root of the space |
| `:unmark` | put down everything picked up with m |
| `:rmspace, :rms [name]` | delete a space and everything in it, into the trash (asks first) |
| `:trash [purge]` | what was deleted — j/k, Enter brings it back, x deletes it for good; :trash purge empties it |
### Boards
| command | what it does |
| --- | --- |
| `:board` | this space's board, in the special workspace |
| `:special` | the special workspace: the board, the agenda and the calendar side by side — S puts it up and away, Tab walks its tiles, 1 … 9 picks the board |
| `:card, :c <title>` | add a card — on the board to the list under the cursor, elsewhere to this space's inbox |
| `:card!` | add a card linked to the open document — gf on it opens the document |
| `:due <when\|->` | due date of the card — on the board, or highlighted in the agenda: today, tm, fri, +3d, +2w, 10-31, 2026-10-31 — - clears |
| `:repeat <rule\|->` | once the card is done, a copy comes back in the inbox: daily, weekly, monthly, yearly, +3d, +2w, +6m — - stops it |
| `:done` | move the selected card into the done list, or back out to the inbox |
| `:task, :step <text>` | add a step to the open card's checklist, below the cursor |
| `:task!` | reword the step under the cursor |
| `:label <name>` | put a label on the card, or take it off when it has it — each name keeps its colour everywhere |
| `:list <name>` | add a column to the board |
| `:list!` | delete the column under the cursor and every card on it |
| `:agenda, :ag` | what is late, due this week, or in hand — across every board |
### Documents
| command | what it does |
| --- | --- |
| `:scratch, :sc [text]` | the scratchpad, lowered over whatever is on screen — Q does the same; with text, a note on it without leaving |
| `:keep [title]` | make the scratch note a document in the folder being browsed — titled by its first line unless given one — and take it off the scratchpad |
| `:new, :n, :o [template] [yyyy-mm-dd] [name]` | start a new document here — from one of the space's templates, dated, named; in the diary from templates/day |
| `:cal, :calendar` | the diary by month — h/l a day, j/k a week, H/L a month, Enter opens the day or starts it |
| `:today` | open today's diary entry, starting one if there is none yet |
| `:next` | open the next node down the list |
| `:prev` | open the previous node |
| `:first` | open the first node in the list |
| `:last` | open the last node in the list |
| `:random` | open something here at random — good for re-reading |
| `:delete, :d, :rm [id]` | delete a node, and everything under it, into the trash (asks first) — u brings it back |
| `:history, :hist` | the open document's earlier versions as diffs — j/k, Enter brings one back (gh) |
| `:backlinks, :bl` | the documents that link to the open one — j/k, Enter opens one (gb) |
| `:source` | show an open markdown file as written, or rendered again |
| `:outline, :toc` | the open document's headings to pick from — gO, in the editor too |
| `:search, :se [text]` | full-text search in this space (empty clears) |
| `:search!` | full-text search across every space — Ctrl-P |
| `:clear, :noh` | clear the search filter |
| `:reload, :r` | re-read the current folder from the server |
### Tiles
| command | what it does |
| --- | --- |
| `:close, :clo` | close the focused tile — Alt-q; asks when its draft could not be written |
| `:only, :on` | close every tile but the focused one |
| `:ls, :buffers, :files` | list the open tiles, % on the focused one |
| `:buffer, :b <n\|name>` | focus a tile by its number in :ls, or by the start of its name |
| `:bnext, :bn` | the next tile — gt |
| `:bprevious, :bp, :bN` | the previous tile — gT |
### Writing
| command | what it does |
| --- | --- |
| `:write, :w` | save the open document — or the card's description being written |
| `:write!` | save even over a newer version saved somewhere else since this one was opened |
| `:wq, :x` | save and leave insert/editor mode |
| `:wq!` | save over a newer version, as :w! does, and leave the editor |
| `:quit, :q` | close the editor, or the document when already reading |
| `:quit!` | discard changes and close the editor |
| `:edit, :e [id]` | edit the open document, or open a node by id |
| `:edit!` | throw away the draft and re-read the document from the server |
| `:name, :title, :rename <text>` | rename what is under the cursor — document, folder, or card on a board; bare, while writing, into the title |
| `:name!` | rename the space you are in — on the board, the list under the cursor |
| `:date <yyyy-mm-dd>` | re-date the open document |
| `:upload, :up` | while writing, attach files at the cursor — otherwise put files into this folder |
| `:upload!` | put files into this folder sealed in the vault — encrypted before they touch the disk |
| `:media` | browse everything you have uploaded — j/k, i inserts it while writing, y copies its address, x deletes |
### Sharing & export
| command | what it does |
| --- | --- |
| `:share` | publish the document behind an unguessable link and copy it |
| `:unshare` | revoke the share link |
| `:link` | mint a new share link for the document and copy it |
| `:copy, :yank` | copy the whole document to the clipboard as markdown |
| `:export, :exp` | download the open document as a .md file |
| `:export!` | download the whole workspace — every space, document and file — as a zip |
| `:download, :dl` | download the file under the cursor, or the open one — the open document goes as :export writes it |
### Vault
| command | what it does |
| --- | --- |
| `:vault` | whether the vault is open — or, the first time, set its password |
| `:unlock` | open the vault with its password, so sealed files can be read |
| `:lock` | close the vault now — it also closes itself when left alone, and on logout |
| `:passwd` | change the vault's password — every sealed file is then re-sealed under a new key, while the vault is open |
| `:encrypt, :seal` | seal the file under the cursor in the vault — a folder stays sealed: every file in it, and every file added later |
| `:decrypt, :unseal` | take the file under the cursor back out of the vault — on a sealed folder, unseal it and every file inside |
### Session
| command | what it does |
| --- | --- |
| `:stats` | word, line and node counts |
| `:set <option>` | vim, novim, clipboard, noclipboard, board, noboard |
| `:backup [login <proton-username> \| logout]` | when the workspace was last mirrored to proton drive — login sets the mirror up, logout forgets its session |
| `:backup!` | back up to proton drive now, rather than when the workspace falls quiet |
| `:sessions [rm <n>]` | every browser signed in, numbered — rm signs one of them out, and locks the vault |
| `:sshkey [add <name> <key> \| rm <name> \| vault <name> on\|off]` | list, add or remove keys allowed to mount the workspace over sftp, and say which may read sealed files |
| `:token [add <name> \| rm <name>]` | list, add or remove tokens that capture into the workspace from outside it — add shows the token once and copies it |
| `:help, :h` | show the key and command reference |
| `:logout` | end the session |
| `:logout!` | end every session, on every device — for a lost phone or a shared computer |