The executable contract of a magit TRANSIENT: clojure.spec over the three
values the component takes, plus the ONE table its vocabulary lives in.
spec WHAT the popup is — closed DATA a pure producer writes
region WHERE it sits — a rectangle a surface builds
host HOW it reaches a terminal — the impure adapter
Two rules keep this honest.
The vocabulary lives here. item-types says what each kind of row
MEANS — :is-flag, :is-valued, :is-command — and transient.clj derives
magit's leading -, the hint bar, the keystroke reducer and the paint from
that map. There is no second copy of the table and no (= :action type)
scattered over the painter, so a new kind of row is added in one place.
This namespace only EXPLAINS. Every *-error returns nil or ONE line of
prose; transient/run! owns the throw, so the
:vis/transient-invalid-spec / -invalid-region / -invalid-host /
-invalid-option envelopes stay in one place, and transient/check is the
same judge answering instead of throwing — which is how a PRODUCER pins its
own band in a unit test without a terminal.
The DATA is CLOSED: an item, a group and a spec carry exactly the keys
declared here, because a mistyped key is otherwise a row that silently does
nothing — a :labl that paints blank, an :arg on a command that never
reaches git. The region and the host are ADAPTERS a surface assembles: they
are checked for everything the component reads and may carry the host's own
extras (:restore! snapshots, a paging host's bookkeeping).
Checked ONCE, at the seam — run! entry, and every value an OPTION brings
in — never per keystroke and never per painted frame.
The executable contract of a magit TRANSIENT: `clojure.spec` over the three values the component takes, plus the ONE table its vocabulary lives in. `spec` WHAT the popup is — closed DATA a pure producer writes `region` WHERE it sits — a rectangle a surface builds `host` HOW it reaches a terminal — the impure adapter Two rules keep this honest. **The vocabulary lives here.** [[item-types]] says what each kind of row MEANS — `:is-flag`, `:is-valued`, `:is-command` — and `transient.clj` derives magit's leading `-`, the hint bar, the keystroke reducer and the paint from that map. There is no second copy of the table and no `(= :action type)` scattered over the painter, so a new kind of row is added in one place. **This namespace only EXPLAINS.** Every `*-error` returns nil or ONE line of prose; `transient/run!` owns the throw, so the `:vis/transient-invalid-spec` / `-invalid-region` / `-invalid-host` / `-invalid-option` envelopes stay in one place, and `transient/check` is the same judge answering instead of throwing — which is how a PRODUCER pins its own band in a unit test without a terminal. The DATA is CLOSED: an item, a group and a spec carry exactly the keys declared here, because a mistyped key is otherwise a row that silently does nothing — a `:labl` that paints blank, an `:arg` on a command that never reaches git. The region and the host are ADAPTERS a surface assembles: they are checked for everything the component reads and may carry the host's own extras (`:restore!` snapshots, a paging host's bookkeeping). Checked ONCE, at the seam — `run!` entry, and every value an OPTION brings in — never per keystroke and never per painted frame.
Types that fire once and close the popup: #{:action}.
Types that fire once and close the popup: `#{:action}`.
Types drawn with magit's leading - and toggled in place: #{:switch :option}.
Types drawn with magit's leading `-` and toggled in place: `#{:switch :option}`.
(group-error group)nil when group is a legal group, else why it is not. Its items are checked
as the items they are, so one call covers the whole group.
nil when `group` is a legal group, else why it is not. Its items are checked as the items they are, so one call covers the whole group.
Every key one group may carry: its heading and the items under it.
Every key one group may carry: its heading and the items under it.
(host-error host)nil when host can paint, flush and answer keystrokes, else why not.
nil when `host` can paint, flush and answer keystrokes, else why not.
Everything the component asks of a terminal. Same story as region-keys:
an adapter may carry more.
Everything the component asks of a terminal. Same story as [[region-keys]]: an adapter may carry more.
(item-error item)nil when item is a legal transient row, else why it is not.
nil when `item` is a legal transient row, else why it is not.
Every key one item may carry. :key is the single keystroke that fires it,
:id what the run reports, :arg the git argument a FLAG contributes.
Every key one item may carry. `:key` is the single keystroke that fires it, `:id` what the run reports, `:arg` the git argument a FLAG contributes.
Every kind of row a transient offers, and what that kind MEANS:
:is-flag wears magit's leading -, toggles IN PLACE and keeps the
popup open
:is-valued carries a value the human is asked for, stored under
[:options id] (the spec's :read-option fetches it)
:is-command fires ONCE and ends the run, reported as :action
A :switch is a flag that is armed and disarmed by its own key; an
:option is a flag that also holds a value; an :action is a verb. The
traits — not the type keyword — are what the component branches on.
Every kind of row a transient offers, and what that kind MEANS:
`:is-flag` wears magit's leading `-`, toggles IN PLACE and keeps the
popup open
`:is-valued` carries a value the human is asked for, stored under
`[:options id]` (the spec's `:read-option` fetches it)
`:is-command` fires ONCE and ends the run, reported as `:action`
A `:switch` is a flag that is armed and disarmed by its own key; an
`:option` is a flag that also holds a value; an `:action` is a verb. The
traits — not the type keyword — are what the component branches on.(option-value-error value)nil when value is what an OPTION may carry into the run state. The one
impure value in the whole component: :read-option is the caller's function,
and whatever it hands back is painted and returned to the caller's caller.
nil when `value` is what an OPTION may carry into the run state. The one impure value in the whole component: `:read-option` is the caller's function, and whatever it hands back is painted and returned to the caller's caller.
(region-error region)nil when region is a rectangle the component can paint into, else why not.
nil when `region` is a rectangle the component can paint into, else why not.
Every coordinate the component reads off a region. Documentation, not a closed set: a region is assembled by a surface and may carry its own extras.
Every coordinate the component reads off a region. Documentation, not a closed set: a region is assembled by a surface and may carry its own extras.
(spec-error spec)nil when spec is a legal transient — every group, every row, every binding
reachable — else why it is not. This is what a producer's own test asks.
nil when `spec` is a legal transient — every group, every row, every binding reachable — else why it is not. This is what a producer's own test asks.
Every key a transient spec may carry. :read-option is the only impure one —
it fetches an OPTION's value and is the caller's, not the popup's.
Every key a transient spec may carry. `:read-option` is the only impure one — it fetches an OPTION's value and is the caller's, not the popup's.
(state-error state)nil when state is a legal run state, else why it is not.
nil when `state` is a legal run state, else why it is not.
The whole run state: which flags are armed, and what the options hold.
The whole run state: which flags are armed, and what the options hold.
The keys only a VALUED item may carry: how its value is asked for and whether it may be echoed. On a switch or a command they describe a value that will never be read.
The keys only a VALUED item may carry: how its value is asked for and whether it may be echoed. On a switch or a command they describe a value that will never be read.
Types that carry a value read from the human: #{:option}.
Types that carry a value read from the human: `#{:option}`.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |