Skip to main content

Module select

Module select 

Source
Expand description

The window’s text selection outside an editor: what a selectable node scopes, what a press-drag across it produces, and what a copy reads.

A view opts text in with NodeSpec::selectable on a container; the core then handles the drag, Shift-arrows, double and triple clicks and Select All. An app reads the result with Core::selection (a Selection) or Core::cell_selection (a CellSelection inside a cells grid), and asks for the text with Core::request_copy, which answers a CopyRequest. There is one selection per window, and an editor’s own selection is the other half of that: starting one clears the other.

A selection is two addresses, a node key and a byte inside that node’s own text, never an index into a frame’s vectors. A frame that no longer builds the node resolves it to nothing; a frame that builds it again resolves it again.

use kui_core::{CellEnd, CellSelection, Endpoint, Key, Selection};

// A drag from byte 3 of one label back to byte 1 of an earlier one.
let scope = Key::ROOT.str("card");
let sel = Selection::new(
    scope,
    Endpoint::new(scope.str("second"), 3),
    Endpoint::new(scope.str("first"), 1),
);
assert!(!sel.is_empty());

// Inside a terminal grid, ends are absolute lines and columns.
let grid = CellSelection::new(Key::ROOT.str("term"), CellEnd::new(10, 3), CellEnd::new(12, 5));
assert_eq!(grid.cols_on(11, 80), Some((0, 80))); // a middle line, edge to edge
assert_eq!(grid.block(true).cols_on(11, 80), Some((3, 5))); // a block: same columns

Structs§

CellEnd
One end of a selection in a cell grid: an absolute line (the grid’s origin_line plus the row) and a column. Absolute because a grid is one screenful of an app’s own history, so a row number means a different line after every scroll.
CellSelection
A selection inside one cells grid.
Endpoint
One end of a selection: the node whose text it lands in, and a byte offset into that node’s content (not into the scope’s).
RangeEnd
One end of the range an app is asked to fill in (Core::selection_range): the data index of the row it is in, and the byte inside that row’s own text. An end outside every virtualised row has no index — it is text the core built and can answer for itself.
Selection
The window’s selection: a scope and two ends of it. anchor is where the press landed and focus is where the pointer is now, so the pair is directed — dragging back past the anchor selects the other way without the two swapping, which is what keeps a drag from feeling like it jumps when it crosses its own start.

Enums§

CopyRequest
What asking for a copy answered (Core::request_copy).
Grain
What a drag-select moves by. A press sets it from the click count the driver counted, the way every text UI does: one click drags by characters, two by words, three by whole runs.

Constants§

ROW_END
A byte that means “the end of the row, whatever its length”: what a Select All puts on the last row of a selectable virtual list the frame did not build, since the core never laid that row out and cannot know where it ends. A selectionrange ask carries it as written, past any row’s length, and the app cuts it to the row. u32::MAX rather than usize::MAX so it survives a wire that spells bytes as numbers.
TINT
What a selection is painted under when nothing else says — the dark base’s tint, and what kui painted before there were themes. The live value is theme.selection, which both a selectable scope and an editor read, because a selection over a label and one over a field sitting side by side must not be two different blues. This constant stays as the floor an crate::edit::EditOptions the core never stamped falls back to.