Draft workspaces as a magit TRANSIENT — the PURE half.
Managing drafts used to be a stack of modal windows: a full-screen picker, then a text-input dialog for the name, then a confirm dialog for the abandon. Three windows to answer one question, each of them hiding the very session the draft belongs to. A draft switch is exactly what a transient is for: a band inside the session's own frame, one keystroke per verb.
This namespace owns WHAT the band offers and WHAT a keystroke means; it
holds no screen, no Lanterna type and no gateway call, so every row, key and
choice is testable without a terminal. dialogs/draft-transient! runs it.
The transient reads:
Drafts ────── Commands c New draft from the committed HEAD d New draft with my uncommitted changes s Switch to another draft… k Abandon draft…
CREATING, SWITCHING and ABANDONING are three different questions, so they
are three different keys and never one list. c and d say which working
tree the new draft starts from — a command each, so nothing has to be armed
as a flag and remembered — while s opens the SWITCH band (trunk and every
draft, ● on the one we are in) and k throws one away. s and k only
exist while a draft exists: with none, there is nowhere to go and nothing to
kill.
Draft workspaces as a magit TRANSIENT — the PURE half. Managing drafts used to be a stack of modal windows: a full-screen picker, then a text-input dialog for the name, then a confirm dialog for the abandon. Three windows to answer one question, each of them hiding the very session the draft belongs to. A draft switch is exactly what a transient is for: a band inside the session's own frame, one keystroke per verb. This namespace owns WHAT the band offers and WHAT a keystroke means; it holds no screen, no Lanterna type and no gateway call, so every row, key and choice is testable without a terminal. `dialogs/draft-transient!` runs it. The transient reads: Drafts ────── Commands c New draft from the committed HEAD d New draft with my uncommitted changes s Switch to another draft… k Abandon draft… CREATING, SWITCHING and ABANDONING are three different questions, so they are three different keys and never one list. `c` and `d` say which working tree the new draft starts from — a command each, so nothing has to be armed as a flag and remembered — while `s` opens the SWITCH band (trunk and every draft, `●` on the one we are in) and `k` throws one away. `s` and `k` only exist while a draft exists: with none, there is nowhere to go and nothing to kill.
(abandon-choices drafts)PURE: the inline single-key chooser rows for "abandon WHICH draft" —
{:key char :label str :id workspace-id}, reusing each row's own band key so
the letter that switches to a draft is the letter that abandons it.
PURE: the inline single-key chooser rows for "abandon WHICH draft" —
`{:key char :label str :id workspace-id}`, reusing each row's own band key so
the letter that switches to a draft is the letter that abandons it.(choice {:keys [action]})PURE: what one finished spec run MEANS — {:action :new :clean? bool},
{:action :switch} (the caller opens switch-spec next) or
{:action :abandon}. nil for Esc.
PURE: what one finished `spec` run MEANS — `{:action :new :clean? bool}`,
`{:action :switch}` (the caller opens `switch-spec` next) or
`{:action :abandon}`. nil for Esc.(draft-spec choice label)PURE: the draft a start-in-choice + typed label asks for, or nil when the
session simply starts in the real project (or the name was left empty).
:clean? is the gateway's seed-from-the-COMMITTED-HEAD flag.
PURE: the draft a `start-in-choice` + typed `label` asks for, or nil when the session simply starts in the real project (or the name was left empty). `:clean?` is the gateway's seed-from-the-COMMITTED-HEAD flag.
(in-draft? rows)PURE: is the session currently inside a draft (rather than on trunk)?
PURE: is the session currently inside a draft (rather than on trunk)?
(row-by-id rows workspace-id)PURE: the row carrying workspace-id, or nil.
PURE: the row carrying `workspace-id`, or nil.
(rows drafts)PURE: the gateway's draft records as band rows, current draft(s) first:
{:key :workspace-id :label :root :is-current}.
Rows past the key pool are dropped rather than rendered unreachable — a keyless row in a keyboard-driven band is a lie.
PURE: the gateway's draft records as band rows, current draft(s) first:
`{:key :workspace-id :label :root :is-current}`.
Rows past the key pool are dropped rather than rendered unreachable — a
keyless row in a keyboard-driven band is a lie.(slash-band path)PURE: {:pressed id-or-nil} when the typed slash path is a question this
band answers — :pressed is the band command the slash already named (the
key the human would otherwise have pressed), nil the band itself.
nil when the line is not one of those: anything that is not /draft, and
every /draft <cmd> <arg> — slash tokenising keeps the argument in the path,
so a line that already carries its own answer runs as the engine slash it
is.
PURE: `{:pressed id-or-nil}` when the typed slash `path` is a question this
band answers — `:pressed` is the band command the slash already named (the
key the human would otherwise have pressed), nil the band itself.
nil when the line is not one of those: anything that is not `/draft`, and
every `/draft <cmd> <arg>` — slash tokenising keeps the argument in the path,
so a line that already carries its own answer runs as the engine slash it
is.(spec drafts)PURE: the transient/run! spec for the draft band — ONE group of commands.
Creating is two commands instead of a command plus a flag: c seeds the
draft from the committed HEAD and d carries the uncommitted working tree
into it, so the band never asks anyone to arm --clean and remember it.
Switching and abandoning are their own keys and only appear while there is
a draft to switch to or throw away.
PURE: the `transient/run!` spec for the draft band — ONE group of commands. Creating is two commands instead of a command plus a flag: `c` seeds the draft from the committed HEAD and `d` carries the uncommitted working tree into it, so the band never asks anyone to arm `--clean` and remember it. Switching and abandoning are their own keys and only appear while there is a draft to switch to or throw away.
(start-in-choice {:keys [action]})PURE: {:start-in :trunk} or {:start-in :draft :clean? bool} from a
start-in-spec run, nil on Esc.
PURE: `{:start-in :trunk}` or `{:start-in :draft :clean? bool}` from a
`start-in-spec` run, nil on Esc.PURE: the transient asking WHERE a new session starts — the TUI twin of the
companion's "Start the session in" menu, and the same vocabulary as the
draft band: t is the project itself, c and d are the two drafts you
can fork.
PURE: the transient asking WHERE a new session starts — the TUI twin of the companion's "Start the session in" menu, and the same vocabulary as the draft band: `t` is the project itself, `c` and `d` are the two drafts you can fork.
(switch-choice drafts {:keys [action]})PURE: what one finished switch-spec run MEANS, in the shape the screen's
draft executor already speaks — {:action :trunk|:draft} plus whatever that
action needs. nil for Esc and for a draft that no longer matches the rows
(one abandoned by someone else while the band was open).
:current? is carried, not resolved: the executor answers "Already on X"
without a second gateway round-trip.
PURE: what one finished `switch-spec` run MEANS, in the shape the screen's
draft executor already speaks — `{:action :trunk|:draft}` plus whatever that
action needs. nil for Esc and for a draft that no longer matches the rows
(one abandoned by someone else while the band was open).
`:current?` is carried, not resolved: the executor answers "Already on X"
without a second gateway round-trip.(switch-spec drafts)PURE: the SECOND band, the one s opens — every workspace this session can
move to, trunk first, the one it is in already marked ●.
It is a band and not a one-row chooser because a draft list is a LIST: the labels have to stay readable, and the row you are on has to be visible.
PURE: the SECOND band, the one `s` opens — every workspace this session can move to, trunk first, the one it is in already marked `●`. It is a band and not a one-row chooser because a draft list is a LIST: the labels have to stay readable, and the row you are on has to be visible.
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 |