KCN-judu/err_marker/cursor does not have a README file

    Model

    pub struct Model {
    tab_width : Int
    ambiguous_wide : Bool
    } derive(Eq,
    Debug
    )

    The layout model: the tab width and whether East Asian Ambiguous characters are wide. Moves are only composed within one model.

    Model::apply

    fn Model::apply(self : Model, m : Move, p : Pos) -> Pos

    Applies a move to a position.

    Model::cluster

    fn Model::cluster(self : Model, cluster : String) -> Move

    The move of one extended grapheme cluster: a tab, a line break ("\n", "\r" or "\r\n"), or a shift by its display width.

    Model::cluster_width

    fn Model::cluster_width(self : Model, cluster : String) -> Int

    Display width of one extended grapheme cluster that is not a tab or a line break, in terminal columns. Rules, in order (see the design page):

    1. a cluster of two regional indicators (a flag), a cluster that contains U+200D ZERO WIDTH JOINER after an Extended_Pictographic base, or a cluster that contains U+FE0F VARIATION SELECTOR-16 is 2;
    2. otherwise the width of the base (first) scalar: 0 for controls, for General_Category Mn, Me, Cf, Default_Ignorable_Code_Point and Hangul medial vowels and final consonants (convention); 2 for East_Asian_Width W and F; 2 for Ambiguous if the model says so; 1 otherwise.

    Model::compose

    fn Model::compose(self : Model, first : Move, then : Move) -> Move

    The move of first followed by then: apply(compose(first, then), p) == apply(then, apply(first, p)).

    Model::equal

    fn Model::equal(Model, Model) -> Bool

    Model::identity

    fn Model::identity(_self : Model) -> Move

    The move that changes nothing.

    Model::new

    fn Model::new(tab_width? : Int, ambiguous_wide? : Bool) -> Model

    A model with tab width tab_width (at least 1; smaller values count as 1) and, if ambiguous_wide, East Asian Ambiguous characters two columns wide.

    Model::newline

    fn Model::newline(_self : Model) -> Move

    One line break: to column 0 of the next line.

    Model::shift

    fn Model::shift(_self : Model, k : Int) -> Move

    k columns to the right (k < 0 counts as 0).

    Model::tab

    fn Model::tab(self : Model) -> Move

    One tab: to the next tab stop.

    Model::text

    fn Model::text(self : Model, text : String) -> Move

    The move of a whole text: the composition of the moves of its clusters. This is a monoid homomorphism: text(u + v) equals compose(text(u), text(v)) whenever u ends on a cluster boundary of u + v.

    Move

    pub enum Move {
    Shift(Int)
    Tab(Int, Int)
    Break(Int, Int)
    } derive(Eq,
    Debug
    )

    How a piece of text moves the cursor, in one of three normal forms. With T(x) = t * (x / t + 1) the next tab stop after column x for tab width t:

    • Shift(k) maps (l, c) to (l, c + k), with k >= 0;
    • Tab(a, b) maps (l, c) to (l, T(c + a) + b), with 0 <= a < t and b >= 0;
    • Break(n, k) maps (l, c) to (l + n, k), with n >= 1 and k >= 0.

    Values can only be built through a Model, which keeps them in normal form, so two moves are equal exactly when they act the same on every position.

    Move::equal

    fn Move::equal(Move, Move) -> Bool

    Pos

    pub(all) struct Pos {
    line : Int
    col : Int
    } derive(Eq,
    Debug
    )

    A cursor position: zero-based line and column, in terminal columns.

    Pos::equal

    fn Pos::equal(Pos, Pos) -> Bool

    clusters

    fn clusters(text : String) -> Array[String]

    The extended grapheme clusters of text (UAX #29).