struct

Termisu::Cell

Inherits Struct / Value / Object

Cell represents a single character cell in the terminal buffer.

Cell contains:

  • grapheme: The Unicode grapheme cluster (single grapheme for leading cells)
  • width: Display column width (0, 1, or 2)
  • continuation: True for trailing cell of a wide grapheme
  • fg: Foreground color (supports ANSI-8, ANSI-256, and RGB)
  • bg: Background color (supports ANSI-8, ANSI-256, and RGB)
  • attr: Text attributes (bold, underline, etc.)

Grapheme and Continuation Cells

Wide characters (CJK, emoji) occupy 2 columns. The Cell model represents this:

  • Leading cell: continuation = false, width = 2, grapheme contains the full grapheme
  • Trailing cell: continuation = true, width = 0, grapheme is empty

Example:

# Leading cell for "中" (width auto-calculated as 2)
lead = Termisu::Cell.new("中")
lead.grapheme      # => "中"
lead.width         # => 2
lead.continuation? # => false

# Trailing continuation cell
trail = Termisu::Cell.continuation
trail.grapheme      # => ""
trail.width         # => 0
trail.continuation? # => true

Compatibility (Public API)

The grapheme property provides backward-compatible access:

cell = Termisu::Cell.new("ABC")
cell.grapheme # => "A" (first grapheme of input-String is stored)

continuation = Termisu::Cell.continuation
continuation.grapheme # => "" (empty for continuation cells)

Constants

CONTINUATION_KEY = Cell.new(continuation: true).key

Key of the canonical continuation cell, so Buffer's key planes can write continuation cells without materializing a Cell.

DEFAULT_KEY = Cell.new.key

Key of the canonical default cell, resolved lazily so default_state? stays a single integer compare.

KEY_STYLE_MASK = (1_u128 << 84) - 1

Style portion of a key (attr + fg + bg, bits 0..83). Cells with equal masked keys render with identical styling (see injectivity notes on #key).

Constructors

new(grapheme : String = " ", continuation : Bool = false, fg : Color = Color.white, bg : Color = Color.default, attr : Attribute = Attribute::None)

Creates a new Cell with the specified grapheme and colors.

Parameters:

  • grapheme: Unicode grapheme cluster to display (if multi-grapheme string is passed, only the first grapheme cluster is stored)
  • continuation: True if this is a trailing cell of a wide grapheme
  • fg: Foreground color (default: white)
  • bg: Background color (default: default terminal color)
  • attr: Text attributes (default: None)

Note: Width is derived from grapheme content to ensure consistency. Continuation cells always have empty grapheme and width 0.

Occupancy invariants enforced:

  • Continuation cells: always empty grapheme, width 0
  • Empty non-continuation: normalized to default space cell (width 1)
  • Leading cells: width derived via grapheme_width (handles VS16, ZWJ, flags)
  • Multi-grapheme strings: only first grapheme is stored; debug log warns of truncation
Source

Class methods

continuation

Continuation cells represent the trailing column occupied by a wide character. They have empty grapheme, width 0, and are never rendered directly.

trail = Termisu::Cell.continuation
trail.continuation? # =&gt; true
trail.width         # =&gt; 0
trail.grapheme      # =&gt; &quot;&quot;
Source
default

default empty cell (space with default colors, width 1, not continuation).

Source

Instance methods

attr
Source
attr=(attr : Attribute)
Source
bg=(bg : Color)
Source
continuation?
Source
default_state?

Returns true when this cell is the canonical default blank cell.

Used by Buffer hot paths (clear/dirtiness accounting) to avoid expensive full-buffer work when rows are already blank.

Source
fg=(fg : Color)

Style setters splice only their own key field instead of re-running compute_key, which would re-derive the grapheme id and take the process-global intern mutex for non-ASCII cells.

Source
grapheme
Source
grapheme=(grapheme : String)
Source
key

Packed identity key: equal keys &lt;=&gt; equal cells (memberwise equality). Buffer hot paths (write dedup, diff scan, default_state?) compare this single UInt128 instead of walking the struct field-by-field.

Bit layout (LSB first):

  • 0..15 attr (UInt16 flags value)
  • 16..49 fg color key (2-bit mode + 32-bit canonical payload)
  • 50..83 bg color key (same encoding)
  • 84..115 grapheme id (ASCII byte direct; non-ASCII interned)
  • 116..117 width (0..2)
  • 118 continuation flag

Injectivity notes: color payload encodes exactly the fields Color#== compares per mode (index for ANSI, r/g/b for RGB), and public Color constructors zero the unused fields, so equal color keys imply Color#==. Grapheme ids are content-interned, so equal ids imply equal strings.

Source
width
Source