Both fire on a _, and you never pick between them: the surrounding text decides. The transform blank handles imperative instructions (make this past tense _); the fluid blank handles free-form lookups (capital of france _). Under the hood they differ in priority, in what they cede to, and in how they're allowed to touch your buffer.
What each one is for
- Transform blank (priority 93). An instruction paired with
_:change boy to girl _,translate to french _, plus a generative branch when there's no target yet (write a poem _). One fused LLM call classifies and rewrites in a single pass. - Fluid blank (priority 92). Everything else: math (
4 * 12 = _), facts, unit conversions, translations of a phrase. One fused call segments the question out of your text and produces a short answer.
The dispatch chain and cede rules
Keyword-bound blanks sit above both at priority 95: if a registered keyword like volume or nvda claims the sentence, both LLM sources cede without a call. The transform blank additionally re-checks for keyword matches in its own supports() before claiming, and its fused call can classify an input as not-a-transform, letting the slot fall through to the fluid blank. The fluid blank is the catch-all at the bottom of the chain.
Opposite write mechanics, deliberately
The fluid blank's fill is always additive: only the _ itself is replaced by the answer; surrounding words are never overwritten, and the splice position comes from the parser, never from the model. The transform blank's job is to rewrite, so it emits a complete new buffer, and the runtime three-way-merges it against what you've typed since: hunks that overlap your own edits are dropped, so typing during the call is never clobbered. The transform blank is opt-in via transform-blank-mode (on by default); the fluid blank is the always-on base layer, catching every _ no blank shape claims.
Related: What is a blank? · Rewrite as you type · Translate inline · GitHub repo