Margin is keyboard-first with a vim grammar. Press ? in the app for this
list. Keybindings are a stability surface (ADR-0021): they only change with
a deprecation cycle. The key set is fixed — there is no custom-keymap
surface yet.
switch unified / side-by-side (pins your choice over the width-based auto layout)
w
toggle line wrap (off clips long lines; wrapped rows scroll as one unit)
za / zA
collapse the cursor’s file / everything (vim folds). Lockfiles and generated bundles fold automatically; the collapse config globs extend the list. Collapsed files show a ▸ header with counts; navigation skips their bodies.
b
toggle the file sidebar
?
toggle help
Esc
close help, then clear the active search
The layout defaults to auto: side-by-side when the diff pane is at least
120 columns wide, unified below that. The status bar shows [split] when
side-by-side is active, and [wrap] when line wrap is on.
stage / unstage the hunk under the cursor (index-only; ADR-0013). Refusals report in the status bar. Available in git worktree and --staged reviews.
x
discard the hunk from the working tree (ADR-0014) — Margin’s only destructive action. Opens a prompt; only typing yes and Enter applies it, Esc cancels. A backup patch lands in .git/margin/trash/ first (margin undo restores). Worktree reviews only. Pass --discard-without-backup to skip the recovery copy for one invocation (ADR-0017); the prompt says so.
m
mark the cursor’s file viewed: sidebar checkmark + the file folds (za reopens it without unmarking). Marks persist per review in the data dir ($XDG_DATA_HOME/margin, $MARGIN_DATA overrides) keyed by content digest — a changed file un-views itself, so a rebase keeps only untouched files marked. Patch/pager reviews keep marks session-only.
c
note on the hunk under the cursor (issue #23): a one-line remark shown inline on the hunk header with a ✎ count in the sidebar. Enter saves, empty input deletes, Esc cancels; reopening an annotated hunk pre-fills the text for editing. Notes persist per review beside viewed marks, keyed by a digest of that hunk — an edited hunk drops its note rather than mislabeling new code. Export them with margin --notes (Markdown, with path:line anchors).
r
reload the diff from its source (also refreshes the sidebar’s staged markers). With -w this happens automatically after changes, waiting while a discard prompt, the file picker, or the note editor is open; notes and the cursor stay with their hunk
In worktree reviews the sidebar marks files that have staged content with a
● dot, so partial staging is visible at a glance.
Strictly additive (issue #26) — everything above works without it.
mouse = false in config or --no-mouse disables
capture and keeps the terminal’s own text selection.