pub struct Sel {
pub anchor: Position,
pub head: Position,
}Expand description
One selection: an anchor (the fixed end) and a head (the end a motion
moves). Both are inclusive char positions — anchor == head is a bare
caret, and a selection with extent covers [start, end] inclusive of both.
§Units
Char columns, like hjkl_buffer::Edit and View::cursor — NOT the
grapheme columns of crate::types::Pos. Mixing the two is silently wrong
on multi-byte text.
§Why the engine owns the anchor
A discipline could keep its own Vec of anchors beside Editor’s secondary
carets, but shift_position may DROP a caret it cannot track, and a
parallel Vec would then desync: anchors and heads would pair up wrong and
the next edit would land on text the user never selected. Keeping both ends
in one struct, shifted together by shift_sel, makes that class of bug
unrepresentable — either the whole selection survives the edit or the whole
selection is dropped.
The primary selection is deliberately asymmetric: its head is
View::cursor and its anchor lives in the discipline’s own state (vim’s
visual_anchor in VimState, helix’s anchor in HelixState). That split
predates multi-cursor and unifying it would rewrite vim’s visual mode, so it
stays. Only the secondary selections live here.
Fields§
§anchor: PositionThe end that stays put while a motion runs.
head: PositionThe end a motion moves; where an edit is applied.