2D grid of cells for rendering terminal content.
Uses a flat tuple for O(1) access per cell and minimal GC pressure. All operations are pure — they return a new buffer without mutating the original.
Fields
width— visible width in columns.height— visible height in rows.cells— flat tuple indexed byy * width + x.
Usage
iex> buffer = Alaja.Buffer.new(80, 24)
iex> buffer = Alaja.Buffer.put(buffer, 10, 5, "X", {255, 0, 0})
iex> Alaja.Buffer.get(buffer, 10, 5)
Summary
Functions
Clears all cells in the buffer.
Creates an empty buffer (width 0, height 0).
Fills a rectangular region with a cell.
Fill with keyword options (alternative API).
Gets the cell at the specified coordinates.
Gets the cell at the specified coordinates (alias for get/3).
Merges two buffers. Cells from buffer2 override cells from buffer1.
Merges a matrix of cells into the buffer at specified position.
Creates a new buffer with the specified dimensions.
Puts a cell at the specified coordinates.
Returns all coordinates in the buffer as a list of {x, y} tuples.
Updates a cell at the specified coordinates with a pre-existing cell struct.
Updates a cell at the specified coordinates with character and optional colors.
Checks if the coordinates are within buffer bounds.
Writes a character to the buffer (alias for put/5-6).
Writes a string with foreground color only (background transparent).
Writes a character with colors to the buffer (alias for put/5-6).
Writes a string (without colour parsing) to the buffer at the given position. Each grapheme is written individually left-to-right.
Types
@type cell() :: Alaja.Cell.t()
@type coordinates() :: {non_neg_integer(), non_neg_integer()}
@type t() :: %Alaja.Buffer{ cells: tuple(), height: non_neg_integer(), width: non_neg_integer() }
Functions
Clears all cells in the buffer.
Parameters
buffer- The buffer to clear
Returns
- Buffer with all cells cleared
Examples
iex> buffer = Buffer.new(10, 10) |> Buffer.put(5, 5, "X", {255, 0, 0})
iex> cleared = Buffer.clear(buffer)
iex> Buffer.get(cleared, 5, 5).char
" "
@spec create_empty_buffer() :: t()
Creates an empty buffer (width 0, height 0).
@spec fill( t(), non_neg_integer(), non_neg_integer(), non_neg_integer(), non_neg_integer(), String.t(), Alaja.Cell.color(), Alaja.Cell.color() ) :: t()
Fills a rectangular region with a cell.
Parameters
buffer- The buffer to fillx1- Starting x coordinatey1- Starting y coordinatex2- Ending x coordinatey2- Ending y coordinatechar- Character to fill withfg- Foreground colorbg- Background color
Returns
- Updated buffer
@spec fill_with_opts( t(), non_neg_integer(), non_neg_integer(), non_neg_integer(), non_neg_integer(), keyword() ) :: t()
Fill with keyword options (alternative API).
@spec get(t(), non_neg_integer(), non_neg_integer()) :: Alaja.Cell.t()
Gets the cell at the specified coordinates.
Parameters
buffer- The buffer to read fromx- The x coordinate (0-based)y- The y coordinate (0-based)
Returns
- The cell at the coordinates, or an empty cell if out of bounds
Examples
iex> buffer = Buffer.new(10, 10) |> Buffer.put(5, 5, "A", {255, 0, 0})
iex> Buffer.get(buffer, 5, 5).char
"A"
iex> buffer = Buffer.new(10, 10)
iex> Buffer.get(buffer, 100, 100).char
" "
@spec get_cell(t(), non_neg_integer(), non_neg_integer()) :: Alaja.Cell.t()
Gets the cell at the specified coordinates (alias for get/3).
Merges two buffers. Cells from buffer2 override cells from buffer1.
Useful for Z-index layering where higher Z buffers are merged on top.
Parameters
buffer1- Base bufferbuffer2- Overlay buffer
Returns
- Merged buffer
@spec merge_matrix(t(), non_neg_integer(), non_neg_integer(), [[Alaja.Cell.t()]]) :: t()
Merges a matrix of cells into the buffer at specified position.
Parameters
buffer- The buffer to merge intox_start- Starting x coordinatey_start- Starting y coordinatematrix- 2D list of cells to merge
Returns
- Updated buffer
@spec new(non_neg_integer(), non_neg_integer()) :: t()
Creates a new buffer with the specified dimensions.
Uses a flat tuple for O(1) access.
Parameters
width- The width of the buffer in cellsheight- The height of the buffer in cells
Returns
- A new buffer struct
Examples
iex> Buffer.new(80, 24)
%Buffer{width: 80, height: 24, cells: {...}}
@spec put( t(), non_neg_integer(), non_neg_integer(), String.t(), Alaja.Cell.color(), Alaja.Cell.color() ) :: t()
Puts a cell at the specified coordinates.
Parameters
buffer- The buffer to modifyx- The x coordinate (0-based)y- The y coordinate (0-based)char- The character to placefg- Optional foreground color as RGB tuplebg- Optional background color as RGB tuple
Returns
- Updated buffer
Examples
iex> buffer = Buffer.new(10, 10)
iex> buffer = Buffer.put(buffer, 5, 5, "X", {255, 0, 0}, {0, 0, 0})
iex> Buffer.get(buffer, 5, 5).char
"X"
@spec range(t()) :: [{non_neg_integer(), non_neg_integer()}]
Returns all coordinates in the buffer as a list of {x, y} tuples.
@spec update_cell(t(), non_neg_integer(), non_neg_integer(), Alaja.Cell.t()) :: t()
Updates a cell at the specified coordinates with a pre-existing cell struct.
@spec update_cell( t(), non_neg_integer(), non_neg_integer(), String.t(), Alaja.Cell.color(), Alaja.Cell.color() ) :: t()
Updates a cell at the specified coordinates with character and optional colors.
@spec valid_coord?(t(), non_neg_integer(), non_neg_integer()) :: boolean()
Checks if the coordinates are within buffer bounds.
Parameters
buffer- The buffer to checkx- The x coordinatey- The y coordinate
Returns
trueif coordinates are validfalseotherwise
@spec write(t(), non_neg_integer(), non_neg_integer(), String.t()) :: t()
Writes a character to the buffer (alias for put/5-6).
@spec write(t(), non_neg_integer(), non_neg_integer(), String.t(), Alaja.Cell.color()) :: t()
@spec write(t(), non_neg_integer(), non_neg_integer(), String.t(), keyword()) :: t()
Writes a string with foreground color only (background transparent).
@spec write( t(), non_neg_integer(), non_neg_integer(), String.t(), Alaja.Cell.color(), Alaja.Cell.color() ) :: t()
Writes a character with colors to the buffer (alias for put/5-6).
@spec write_string(t(), non_neg_integer(), non_neg_integer(), String.t()) :: t()
Writes a string (without colour parsing) to the buffer at the given position. Each grapheme is written individually left-to-right.
Characters beyond the buffer width are silently skipped.