Skip to main content

Crate leaf_ffi

Crate leaf_ffi 

Source
Expand description

leaf-ffi — the Swift / C-ABI frontend binding for leaf.

This is the native-Apple analogue of leaf-wasm: it takes leaf-core’s frontend-neutral Doc — the byte-offset caret model and the AST→glyph VisualMap — and exposes it across a C ABI (via UniFFI) in the shape an AppKit/SwiftUI renderer wants. Core stays the single source of truth for the text, the caret math, and the offset⇄position mapping; the Swift side only paints glyphs and forwards key/mouse events back in, exactly as the TUI, gpui, and wasm frontends do.

§The boundary is style runs, not glyphs

Doc::build_visual resolves the document to rows of per-character glyphs, each tagged with a semantic Role and the author’s emphasis. Sending one object per character would make every keystroke O(document) in boundary crossings. Instead LeafDoc::view coalesces each row’s glyphs into maximal runs of identical style and ships those — a handful of records per line. The Swift renderer maps each run’s role to a font/size/weight and its emphasis flags to traits, the native counterpart of the TUI’s to_ratatui and the web’s CSS class.

§Core owns the grid; Swift owns the pixels

Core lays a row out in whole character columns (a terminal-cell measure), and every offset⇄position method speaks that grid. It deliberately does not dictate presentation. So a native renderer is proportional — body text in a real family, headings by size and weight, code in a monospace panel — and never multiplies col × cell_width. It lets NSLayoutManager / Core Text shape each row, places the caret at DocView::caret_ch (a UTF-16 offset, which is exactly what NSAttributedString and NSTextView count in), and hit-tests a click through characterIndex(for:), feeding the resulting row + UTF-16 offset back through LeafDoc::click_ch. Core measures nothing in pixels; Swift positions nothing in the model.

§Threading

A UniFFI object is handed to Swift as a reference-counted handle whose methods take &self, so the Doc lives behind a Mutex. Every call locks, edits or reads, and returns a fresh DocView — one boundary crossing both mutates and repaints, same as the wasm frontend. Drive it from the main thread.

Structs§

Boundary
What a drawn block boundary separates. The FFI mirror of leaf_core::Boundary.
Capabilities
Which formatting controls this document’s format can spell — the toolbar’s enabled state, one flag per button, from LeafDoc::capabilities. Mirrors leaf_core::Capabilities, where the reasoning lives.
DirectiveAttr
One {key=value} attribute of a DirectiveView. A record rather than a tuple because UniFFI has no tuple type; an absent value flattens to "", since a bare attribute is a flag and the distinction from key="" has no consumer on this side.
DirectiveView
A leaf directive (::name{…}) — a standalone block with no body, drawn in DocView::rows as a one-row ⧉ name placeholder. A frontend that knows the host app’s vocabulary reads this and paints the real thing over the rows in [start_row, end_row) — a web view for diaryx’s ::embed{src=…}, say — exactly as a grid-drawing one replaces a TableView’s picture rows. One that doesn’t just paints the placeholder, which is already framed by the directive panel chrome.
DocView
A rendered frame: the rows to paint, where the caret sits, and the toolbar state — everything the Swift side needs for one repaint, in one value. Returned by every view-producing method.
DropTargetView
Where a dragged block would land — what LeafDoc::drop_target_at answers with, and the FFI mirror of leaf_core::DropTarget. A drop is aimed at a row and lands at a boundary, and a host needs both halves: the offset to hand LeafDoc::move_block, and the row to draw the indicator above — rows.len() for a drop below everything.
FootnoteDefView
A footnote definition and the reference that sends a reader to it — what LeafDoc::footnote_definition_at_caret answers with, and the FFI mirror of leaf_core::FootnoteDef.
FootnoteView
A footnote reference and the note it names — what LeafDoc::footnote_at answers with. The FFI mirror of leaf_core::FootnoteRef.
HeadingView
The heading a place sits under — what LeafDoc::heading_at answers with, and the FFI mirror of leaf_core::Heading.
Highlight
A host-painted range of the source — an annotation’s footprint, a search hit. The FFI shape of leaf_core::Highlight; see LeafDoc::set_highlights.
LandingView
Where a locator lands — what LeafDoc::locate answers with, and the FFI mirror of leaf_core::Landing.
LeafDoc
A live leaf document bound for a native Apple frontend: leaf_core::Doc plus the wrap width the current viewport implies, behind a mutex. Constructed from an in-memory string and driven entirely through method calls — there is no filesystem behind it.
MathHeight
A per-formula measured height, the way a renderer that reserves rows (rather than laying pictures out in its own units) reports one back — the input half of the loop LeafDoc::set_math_rows closes. The Swift views lay a formula out in points and never need this.
MathPicture
A typeset formula: a standalone SVG document and where its baseline is. The peer of leaf_math::MathPicture; see typeset_math.
MathView
One formula standing as a picture: what to typeset and where its picture goes. The peer of leaf_core::MathInfo. Two shapes:
MediaHeight
A per-destination measured height, the way Swift reports one back — the input half of the loop LeafDoc::set_media_rows closes.
MediaSourceView
One <source> alternative of a block media element — a candidate URL plus whichever of the two things HTML picks a <source> by: a media query (<picture>) or a MIME type (<video>/<audio>).
MediaView
One block-level image, video, or audio: which rows core reserved for it and what to build there. The peer of leaf_core::MediaInfo, and the media analogue of DirectiveView — a frontend skips the rows in start_row..end_row and lays its own view over them, rather than painting the 🖼/🎬/🔊 placeholder glyphs core put there for a surface that can’t.
Row
One visual line: its styled runs plus the row-level flags a frontend draws chrome from.
RowCol
A visual position: a row index plus a UTF-16 offset within that row’s text — the coordinate the geometry side (Core Text) draws from. Returned by LeafDoc::pos_for_offset, the bridge from a source offset (what a UITextPosition wraps) to where it sits on screen.
RowRange
The rows a source range covers, both ends inclusive — what a frontend slices out of a frame to draw a block somewhere other than where it sits: a footnote peek, a link peek, a landing flash. Returned by LeafDoc::row_range_for.
Run
One maximal span of same-styled glyphs on a visual row — the unit the Swift renderer turns into a single styled attributed-string run.
SelectionQuote
A selection cited out of the source — the text, a little of what surrounded it, and the byte range it came from. The FFI shape of leaf_core::Quote; see LeafDoc::selection_quote.
TableCellLineView
One visual line of a table cell: its styled runs and the source offsets bounding it. A cell is usually one line, but an in-cell hard break (an inline <br>) splits it into several — each its own line here, so the frontend shapes and caret-maps them independently (the byte↔UTF-16 offset math a cell needs holds within a line, which carries no break). The runs are unwrapped: column width — and any soft wrap within it — is the frontend’s to decide.
TableCellView
One cell of a table’s structural grid: its content as one or more visual lines, the column alignment its text honours, and the source range the whole cell occupies (where a click or the caret lands).
TableRowView
One row of a table’s structural grid; a header row draws bold and is ruled off from the body below it.
TableView
A table described structurally rather than as the monospace box-glyph picture that spells it in DocView::rows. A proportional renderer draws its own grid from this — columns sized to content, real borders — and SKIPS the picture rows in [start_row, end_row). The two describe the same cells at the same source offsets, so the caret lands identically either way. See leaf_core::TableInfo.
TextCounts
How much writing there is — over the whole document, or over the selection. The FFI shape of leaf_core::TextCounts; see LeafDoc::counts for what is counted and what isn’t.

Enums§

Align
How a block’s lines are set across the measure — the closed vocabulary LeafDoc::set_alignment writes and LeafDoc::alignment_at_caret reports.
BlockClass
The block kinds core tells apart — the vocabulary a Boundary is spelled in. The FFI mirror of leaf_core::BlockClass; Other covers every kind core doesn’t separate out, so a frontend’s match stays exhaustive as the list grows.
FontFace
The face a run is set in: one of CSS’s four generics, or the family the author named.
FontFamily
The face a run is set in — CSS’s generic families, less fantasy and system-ui, neither of which an author asks for. What LeafDoc::set_font_family writes.
FontSize
How large a run is set: a SizeStep relative to the text around it, or the point size the author asked for. What LeafDoc::set_font_size writes and LeafDoc::font_size_at_caret answers.
LeafError
A parse failure constructing a document — the only fallible entry point. Every other method is infallible (it operates on an already-parsed model), so they return a DocView directly.
LineFlow
How the rich view treats a soft break (a bare newline inside a paragraph) — the argument to LeafDoc::set_line_flow. Mirrors leaf_core::LineFlow; Fold is the default (soft breaks reflow into the paragraph, as before).
LineHeight
How far apart a block’s lines are set: a LineSpacing from the menu’s three, or the ratio the author asked for. FontSize’s peer one property along, and with no unit at all — a line height is a multiple.
LineSpacing
How far apart a block’s lines are set, as a multiple of the theme’s own line height — the vocabulary LeafDoc::set_line_spacing writes.
MarkColor
The colour of a highlight — the closed palette LeafDoc::set_mark_color writes and DocView::mark_color reports.
MarkupMode
How much of the source markup the rich view exposes — the argument to LeafDoc::set_markup_mode. Mirrors leaf_core::MarkupMode; None is the default (the clean surface Diaryx ships, with typed syntax kept literal).
MediaKind
What a block-level media placeholder is, so Swift knows which view to build over the rows core reserved: an NSImageView/UIImageView, or an AVPlayerView with or without a picture to show. The peer of leaf_core::MediaKind.
SizeStep
How large a run is set relative to the text around it — CSS’s <absolute-size> keywords with medium removed, because medium is absence. What LeafDoc::set_font_size writes.
TableAlignment
A table column’s text alignment — the argument to LeafDoc::table_set_alignment. Mirrors twig’s Alignment.
TextColor
A run’s foreground colour: one of the seven MarkColor names, or the RGB triple the author asked for.

Functions§

typeset_math
Typeset tex — the text between a formula’s delimiters, as a MathView hands it over — to a picture. display is the view’s display; size is the font size in points the formula is set at (an inline formula takes the run’s, a block the body’s); r, g, b, a are the ink, as bytes. A theme change is a re-render with a new colour.