Skip to main content

Module ropetext

Module ropetext 

Source
Expand description

A text editing model for terminal editors.

ropetext owns text, the cursor, the selection, the edit history, motions, and soft-wrap layout. It owns nothing else, and the omissions are deliberate:

  • No renderer. Layout returns visual lines and cell coordinates in this module’s own plain geometry types. Painting belongs to the caller.
  • No input handling. Keys never reach this module. It exposes operations; deciding which key performs which operation is the caller’s business.
  • No syntax, no markdown. What a construct means never enters. Where a syntax layer must be heard from — wrapping has to know which characters are hidden and how far a row is inset — it is heard as data passed in, not as a trait this module calls back into.
  • No search, no clipboard, no registers. It hands out the text in a range; what a caller matches against it or stores it in is not its concern.

§It knows nothing of kimün

The omissions above are not incidental — they are the reason this module was written. It replaced a third-party textarea whose contract kept leaking editor policy (its own undo keybindings, its own idea of what a line is) into callers, and it earns its place only by staying narrower than what it replaced. The name carries no kimun prefix for the same reason: anything kimün-flavoured that tries to move in should look wrong on sight.

This was a separate workspace crate, which made that a compiler rule — a crate cannot say crate::settings::Theme. It was folded in because kimun-notes is published to crates.io, and crates.io refuses to publish a crate that path-depends on an unpublished one: a workspace member the published crate depends on is either published forever or not a crate. This had no API worth stabilising, so it stopped being a crate.

The rule outlived the crate. Nothing here may name crate:: outside crate::ropetext::, checked in .github/workflows/check.yml now that the crate graph no longer can. That is the one property extraction depends on: going back out to a crate — for a reusable editor widget, say — is a git mv and a manifest, with nothing to untangle first.

§Positions are checked, never approximated

A Position can only be built by asking a Text for one, and it carries the Revision it was built against. A position the text cannot address has no value at all — the constructor returns None rather than clamping to something nearby — and a position used against a later revision is rejected rather than silently read as some other place in the buffer. The one call that approximates, Text::position_at_byte_snapped, is named for it.

Modules§

motion
Where a movement lands.

Structs§

Cell
A screen cell, relative to the top-left of the laid-out text.
Change
The outcome of a committed transaction, an undo, or a redo.
Column
A column within one row, counted in Unicode scalars.
Edit
One replaced region, in the coordinates of the text after the change.
EditBuffer
The open note’s text, cursor, selection and edit history.
Layout
Where a text’s rows break at a given width.
Metrics
Cell measurements a layout needs, so a caller that renders differently can say so instead of the layout assuming.
Position
A place in a text.
Revision
Which state of a text a value refers to.
RowHints
What a syntax layer tells the layout about one logical row.
Snapshot
A text with its cursor and selection, taken at one moment.
Span
An ordered, single-revision range between two Positions.
Text
A text, as a value.
Txn
A set of edits that lands as one undo group.
Viewport
The visible part of a scrolled layout.
VisualLine
One drawn line: a slice of a logical row that fits the width.