///|
/// How a selection was anchored, mirroring Monaco's `SelectionStartKind`. A
/// plain click anchors `Simple`; double/triple-click anchors `Word`/`Line`, and
/// continuation gestures preserve and extend the corresponding anchor range.
pub(all) enum SelectionStartKind {
Simple
Word
Line
} derive(Eq, Debug)
///|
/// The cursor state on either the model or the view model, a faithful port of
/// Monaco's `cursorCommon.ts` `SingleCursorState`. `selection_start` is the
/// anchor *range* (a region for word/line selection, collapsed for simple) and
/// `position` is the moving active end; the derived `selection` carries the
/// orientation. Positions are one-based (`line_number`, UTF-16 `column`),
/// matching Monaco's `Position`.
///
/// The two leftover-visible-column fields retain the desired visual column
/// while vertical movement crosses lines of different widths. The anchor-side
/// value is preserved while extending a selection; collapsing a selection
/// replaces both values with the active movement residue.
pub struct SingleCursorState {
selection_start_start : @base_common.Position
selection_start_end : @base_common.Position
selection_start_kind : SelectionStartKind
selection_start_leftover_visible_columns : Int32
position : @base_common.Position
leftover_visible_columns : Int32
} derive(Eq, Debug)
///|
/// Builds a cursor state from an explicit anchor range and active position.
pub fn SingleCursorState::SingleCursorState(
selection_start_start : @base_common.Position,
selection_start_end : @base_common.Position,
selection_start_kind : SelectionStartKind,
position : @base_common.Position,
selection_start_leftover_visible_columns~ : Int32 = 0,
leftover_visible_columns~ : Int32 = 0,
) -> SingleCursorState {
{
selection_start_start,
selection_start_end,
selection_start_kind,
selection_start_leftover_visible_columns,
position,
leftover_visible_columns,
}
}
///|
/// A collapsed cursor at `position` (anchor and active coincide, `Simple`).
fn SingleCursorState::collapsed(
position : @base_common.Position,
) -> SingleCursorState {
SingleCursorState(position, position, Simple, position)
}
///|
/// Whether the anchor range is collapsed to a point.
fn SingleCursorState::selection_start_is_empty(
self : SingleCursorState,
) -> Bool {
self.selection_start_start.equals(self.selection_start_end)
}
///|
/// The derived selection (anchor, active) carrying orientation. Transcribes
/// Monaco's `SingleCursorState._computeSelection`: an active end strictly after
/// the anchor's start uses that start as the selection anchor; equality or a
/// position before the start (selecting backward over a word/line) uses the
/// anchor range's end.
pub fn SingleCursorState::selection(
self : SingleCursorState,
) -> @core.Selection {
if self.selection_start_is_empty() ||
not_before_or_equal(self.position, self.selection_start_start) {
Selection(self.selection_start_start, self.position)
} else {
Selection(self.selection_start_end, self.position)
}
}
///|
/// Whether this state selects any text (mirrors Monaco `hasSelection`).
pub fn SingleCursorState::has_selection(self : SingleCursorState) -> Bool {
!self.selection().is_empty() || !self.selection_start_is_empty()
}
///|
/// Moves the cursor, transcribing Monaco's `SingleCursorState.move` (`move` is
/// a reserved word here). In selection mode only the active `position` moves
/// (the anchor is kept); out of selection mode the whole state collapses to the
/// new point.
pub fn SingleCursorState::moved(
self : SingleCursorState,
in_selection_mode : Bool,
position : @base_common.Position,
leftover_visible_columns~ : Int32 = 0,
) -> SingleCursorState {
if in_selection_mode {
{ ..self, position, leftover_visible_columns, }
} else {
SingleCursorState(
position,
position,
Simple,
position,
selection_start_leftover_visible_columns=leftover_visible_columns,
leftover_visible_columns~,
)
}
}
///|
/// Whether `a` is strictly after `b` in reading order, i.e. `!a.isBeforeOrEqual(b)`.
fn not_before_or_equal(
a : @base_common.Position,
b : @base_common.Position,
) -> Bool {
!a.is_before_or_equal(b)
}
///|
pub extend SelectionStartKind with Debug::{to_repr}
///|
pub extend SelectionStartKind with Eq::{equal, not_equal}
///|
pub extend SingleCursorState with Debug::{to_repr}
///|
pub extend SingleCursorState with Eq::{equal, not_equal}