struct Termisu::Cell

Overview

Cell represents a single character cell in the terminal buffer.

Cell contains:

Grapheme and Continuation Cells

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

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 #ch property provides backward-compatible access:

cell = Termisu::Cell.new('A')
cell.ch # => 'A' (first codepoint of grapheme)

continuation = Termisu::Cell.continuation
continuation.ch # => ' ' (space for continuation cells)

Defined in:

termisu/cell.cr

Constructors

Instance Method Summary

Constructor Detail

def self.continuation : Cell #

Creates a continuation cell for wide graphemes.

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? # => true
trail.width         # => 0
trail.grapheme      # => ""

[View source]
def self.default : Cell #

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


[View source]
def self.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

[View source]
def self.new(ch : Char, fg : Color = Color.white, bg : Color = Color.default, attr : Attribute = Attribute::None) : self #

Creates a Cell from a single character (compatibility constructor).

This constructor maintains backward compatibility with the Char-based API. Width is auto-calculated from the character's codepoint.

Note: Control characters (C0/C1) produce width 0 non-continuation cells. This is permitted for internal sentinel usage (e.g., Buffer#invalidate uses NUL cells as invalid markers). The public write path (Buffer#set_cell) guards against control characters before reaching this constructor.


[View source]

Instance Method Detail

def ==(other : Cell) : Bool #

Checks if this cell equals another cell.

Two cells are equal if all fields match: grapheme, width, continuation, fg, bg, attr.


[View source]
def attr : Attribute #

[View source]
def attr=(attr : Attribute) #

[View source]
def bg : Color #

[View source]
def bg=(bg : Color) #

[View source]
def ch : Char #

Gets the first character of the grapheme (compatibility property).

Returns:

  • First codepoint of grapheme for leading cells
  • Space (' ') for continuation cells or empty grapheme

This provides backward compatibility with Char-based API.


[View source]
def ch=(value : Char) #

Sets the cell to a single character (compatibility setter).

This rewrites the cell to narrow grapheme mode with width calculated from the character's codepoint.

Provides backward compatibility with Char-based API.


[View source]
def continuation? : Bool #

[View source]
def default_state? : Bool #

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.


[View source]
def fg : Color #

[View source]
def fg=(fg : Color) #

[View source]
def grapheme : String #

[View source]
def reset #

Resets the cell to default state (space, white on default background, no attributes, width 1, not continuation).


[View source]
def width : UInt8 #

[View source]