blank-trigger-mode controls when a typed _ actually fires its blank. immediate, the default, triggers the moment the underscore lands at the end of your buffer. spaced waits for a confirming space after the underscore, which is the mode to pick if you write markdown, because it lets _italic_ complete without a blank firing mid-word.
The problem it solves
In markdown surfaces (Reddit comments, GitHub issues, Discord, anywhere _ means emphasis), typing _italic_ would fire the blank on the first underscore before you can type the closing one. spaced mode defers the trigger until a space follows, so a bare _ is just a character. The docs' summary of the semantics is exactly two clauses: bare _ is inert; _ followed by a space confirms intent and fires.
The trade, stated plainly
| Mode | Behaviour | Cost |
|---|---|---|
immediate (default) | _ fires the instant you type it | _italic_ gets interrupted |
spaced | _ fires only once a space follows | One extra keystroke per intentional blank |
The default stays immediate to preserve the snappy original behaviour for existing users; markdown-heavy writers (Reddit, GitHub, Discord, any editor that interprets underscores) are the audience the docs point at spaced.
Edge behaviour worth knowing
- Any whitespace confirms:
weather _followed by a space or a newline both fire in spaced mode. - A mid-buffer underscore (
hello _ worldwith the cursor elsewhere) fires in neither mode; triggering is about the end of the buffer. - A completed
_italic_never fires in spaced mode, and even_italic_with a trailing space is refused by a word-boundary check, so emphasis-wrapped words don't turn into accidental blanks. - The mode gates every trigger path consistently, including the keyboard intercept that value blanks like
volumeandbrightnessuse.
How it works underneath
A _ can reach the runtime through more than one door: the immediate keystroke intercept that value blanks use, the debounce bypass that fires a blank without waiting, and the scheduled re-check that runs a moment after you pause. The scalar gates all of them consistently, so there is no path where a bare underscore sneaks through in spaced mode. In spaced mode the conditions simply tighten from "buffer ends with _" to "buffer ends with _ plus whitespace".
Setting it
blank-trigger-mode: spaced in ~/.cues/OPENCUES.md (hot-reload, ~2 seconds), or cycle it via opencues settings _. If a blank ever seems dead, this scalar is the second thing to check after keyword position: in spaced mode an unconfirmed _ sitting at the end of your text is working as designed, waiting for its space. The blank-not-firing checklist walks the full diagnosis order.
Related: Why is my blank not firing? · What is a blank? · What is OPENCUES.md? · GitHub repo