Selection is exposed semantically — blocks and offsets, marks, comment and
suggestion IDs — never as canvas geometry. Your UI stays decoupled from how
Revise lays text out.
Reading
Subscribe to follow it:
observe() publishes the snapshot directly; subscribe() publishes
{ snapshot } if you prefer the event shape. Both return an unsubscribe
function and are memoised, so identical selections do not re-render your UI.
Capture and restore
The problem: your “Add comment” popover has an input. The moment the user
clicks into it, the editor loses focus and the selection they were commenting
on is gone.
capture() returns a deeply frozen, document-scoped snapshot that stays valid
after focus moves away. It returns null only when there is no addressable
selection or caret at all.
restore() puts the selection back and refocuses the editor. It returns a
typed failure when the editor is unavailable, the document is read-only, the
capture belongs to a different document, or the captured blocks no longer
exist — all of which are ordinary outcomes when your UI stays open across an
agent edit.
Capture on open, restore on submit. Do not hold a capture across a document
switch: it is scoped to one document and will refuse to restore into another.
Clearing
For agents
Agents get the same information through the get_selection tool, which returns
one semantic snapshot: selected text, caret or range positions, portable target
segments, active formatting, comment IDs, and suggestion IDs — and no geometry.
This matters because an outside agent does not receive the context Revise’s own
agent gets injected automatically. If your model needs to act on “the bit the
user highlighted”, give it get_selection.