# Selections and document positions

Read caret ranges, select text or nodes, and preserve the toolbar's editing target.

A selection identifies the target of the next edit: a caret, text range or complete node. It belongs to Editor state; the View projects it into visible highlighting.

## Read the current selection

```ts [Read selected text]
const { doc, selection } = editor.state.pm
const { from, to, empty } = selection
const text = doc.textBetween(from, to, '\n')
```

`empty` reports whether the range is collapsed; an ordinary caret has equal `from` and `to` positions. These boundaries follow document order. Read `anchor` / `head` when drag direction matters.

Positions use ProseMirror's document coordinates, rather than plain-text indexes or pixels. In a document containing one paragraph with `Hello`, the paragraph starts at `0` and text starts at `1`; select the word with `{ from: 1, to: 6 }`. Container boundaries also consume positions, so string lengths cannot locate arbitrary nested content. Use [mounted View geometry](/en/api/view) to translate screen coordinates.

## Set a text or node selection

```ts [Select the word in the Hello document above]
editor.chain().setTextSelection({ from: 1, to: 6 }).focus().run()
```

A number passed to `setTextSelection(position)` places a caret; `{ from, to }` selects a range. Use `setNodeSelection(position)` for a selectable image or other complete node, with the position immediately before that node. `selectAll()` selects the document. A node selection is generally nonempty but does not represent an ordinary text range.

Do not reuse numeric positions from another document or an earlier transaction without validation. Commands in a chain share a transaction. When a complex command changes structure before using later positions, map those positions through `tr.mapping`. Asynchronous work must also validate its document, target and task lifetime.

## Preserve the toolbar target

A bold button can call `editor.chain().focus().toggleBold().run()`. Without a position, `focus()` restores the current selection rather than moving to the end. Avoid hardcoding `focus('end')` on every toolbar click.

Use `editor.isActive('bold')` for active formatting and `editor.getAttributes('heading').level` for heading attributes. Both are read-only queries. Word's effective formatting can also inherit from styles and needs the corresponding Word reader; see [toolbar integration](/en/build/commands).

## Subscribe to changes

Use `selectionUpdate` for selection statistics. Toolbars also depend on content changes and stored formatting at the caret, so they can observe `transaction` and read a bounded set of values. Moving the caret should not serialize or save the whole document. See [lifecycle and events](/en/concepts/lifecycle) for subscription cleanup.
