EditorRenderer
Multi-line text editor with vertical scrolling, word wrapping, and a movable caret. The TUI analog of pi-tui's `Editor` component — single-line input's big sibling. Pure renderer: the caller owns the `text`, `cursor` `[row, col]`, `scrollOffset`, and (optionally) the paste markers, and mutates them from a `RetainedTuiLoop` key handler or a live component. This renderer only paints the snapshot. Layout: ┌─ Title ─────────────────────┐ │ first line │ │ sec|ond line │ <- caret between 'sec' and 'ond' │ third line │ └──────────────────────────────┘ The caret is painted with reverse-video and tagged with the {@see FocusableInterface::CURSOR_MARKER} APC so the loop can position the hardware terminal cursor at the caret cell for IME — the multi-line analog of {@see TextInputRenderer}'s single-line caret. When the cursor row is outside the visible scroll window, the renderer auto-centers the scroll around it (the caller may override via `scrollOffset`). Word-wrap is on by default; long lines wrap at the node width and the cursor's `[row, col]` is interpreted in the *wrapped* coordinate system so navigation stays consistent. Node props (all optional): - `text` string Multi-line content. Lines separated by "\n". - `cursor` array `[row, col]` zero-indexed in wrapped coordinates. Default: [0, 0]. - `scrollOffset` int First wrapped row to show. Default: auto-center on cursor. - `wrap` bool Word-wrap long lines. Default: true. - `title` string Title shown in the top border. Default: ''. - `border` bool Draw a border. Default: true. - `focused` bool Override focus. Default: context.focused(). - `placeholder` string Shown when text is empty. Default: ''. - `paddingX` int Horizontal padding. Default: 0. - `showScrollInfo` bool Show `row/total` in the bottom border. Default: true.
EditorRenderer::supports()
public function supports(Milpa\Live\ValueObjects\Tui\TuiNode $node): boolTrue only for `editor` nodes — dispatch is by declared node type, never by where the node came from.
Parameters
| Name | Type | Description |
|---|---|---|
| $node | Milpa\Live\ValueObjects\Tui\TuiNode |
EditorRenderer::render()
public function render(Milpa\Live\ValueObjects\Tui\TuiNode $node, Milpa\Live\ValueObjects\Tui\TuiRenderContext $context): Milpa\Live\ValueObjects\Tui\TuiFrameDraws the visible window of text with wrapping applied and the caret at its current position.
Parameters
| Name | Type | Description |
|---|---|---|
| $node | Milpa\Live\ValueObjects\Tui\TuiNode | |
| $context | Milpa\Live\ValueObjects\Tui\TuiRenderContext |
EditorRenderer::hasCaret()
public function hasCaret(string $output): boolWhether the rendered output carries the caret marker, i.e. whether this editor is the node holding the caret.
Parameters
| Name | Type | Description |
|---|---|---|
| $output | string |
EditorRenderer::caretPosition()
public function caretPosition(string $output): ?arrayThe row and column of the caret within the rendered output, accounting for wrapped lines, or null when the output does not carry the marker.
Parameters
| Name | Type | Description |
|---|---|---|
| $output | string |