Raxol.Terminal.Renderer (Raxol Terminal v2.6.1)

Copy Markdown View Source

Terminal renderer module.

This module handles rendering of terminal output using ANSI escape codes, including:

  • Character cell rendering
  • Text styling (colors, bold, italic, underline)
  • Cursor rendering
  • Performance optimizations (style batching, caching)

Integration with Other Modules

The Renderer module works closely with several specialized modules:

Manipulation Module

  • Receives text and style updates from the Manipulation module
  • Renders text with proper styling and positioning
  • Handles text insertion, deletion, and modification

Selection Module

  • Renders text selections with visual highlighting
  • Supports multiple selections
  • Handles selection state changes

Validation Module

  • Renders validation errors and warnings
  • Applies visual indicators for invalid input
  • Shows validation state through styling

Performance Optimizations

The renderer includes several optimizations:

  • Only renders changed cells
  • Batches style updates for consecutive cells
  • Minimizes terminal output
  • Caches rendered output when possible

Usage

# Create a new renderer
buffer = ScreenBuffer.new(80, 24)
renderer = Renderer.new(buffer)

# Render with selection
selection = %{selection: {0, 0, 0, 5}}
output = Renderer.render(renderer, selection: selection)

# Render with validation
validation = Validation.validate_input(buffer, 0, 0, "text")
output = Renderer.render(renderer, validation: validation)

Summary

Functions

Clears the cursor position.

Gets the current content of the screen buffer.

Creates a new renderer with the given screen buffer.

Renders the terminal content. The optional opts arguments are currently unused (accepted for call-site compatibility).

Renders a single row (0-based) to its ANSI string. Out-of-range rows render as "". A row is a pure function of its own cells -- it carries no pen state from the row above, so a row rendered in isolation is byte-identical to its slice of the full frame.

Renders each buffer row to its own ANSI string, in order.

Sets the cursor position.

Updates the font settings.

Updates the theme settings.

Starts a new renderer process.

Stops the renderer process.

Types

t()

@type t() :: %Raxol.Terminal.Renderer{
  cursor: {non_neg_integer(), non_neg_integer()} | nil,
  font_settings: map(),
  screen_buffer: Raxol.Terminal.ScreenBuffer.t(),
  style_batching: term(),
  style_cache: map(),
  theme: map()
}

Functions

clear_cursor(renderer)

Clears the cursor position.

Examples

iex> screen_buffer = ScreenBuffer.new(80, 24)
iex> renderer = Renderer.new(screen_buffer)
iex> renderer = Renderer.set_cursor(renderer, {10, 5})
iex> renderer = Renderer.clear_cursor(renderer)
iex> renderer.cursor
nil

get_content(renderer, opts \\ [])

Gets the current content of the screen buffer.

Parameters

  • renderer - The renderer to get content from
  • opts - Options for content retrieval
    • :include_style - Whether to include style information (default: false)
    • :include_cursor - Whether to include cursor position (default: false)

Returns

  • {:ok, content} - The current content
  • {:error, reason} - If content retrieval fails

Examples

iex> get_content(renderer)
{:ok, "Hello, World!"}

new(screen_buffer, theme \\ %{}, font_settings \\ %{}, style_batching \\ false)

Creates a new renderer with the given screen buffer.

Examples

iex> screen_buffer = ScreenBuffer.new(80, 24)
iex> renderer = Renderer.new(screen_buffer)
iex> renderer.screen_buffer
%ScreenBuffer{}

render(renderer, opts \\ [], additional_opts \\ [])

Renders the terminal content. The optional opts arguments are currently unused (accepted for call-site compatibility).

render_row(renderer, y)

@spec render_row(t(), non_neg_integer()) :: String.t()

Renders a single row (0-based) to its ANSI string. Out-of-range rows render as "". A row is a pure function of its own cells -- it carries no pen state from the row above, so a row rendered in isolation is byte-identical to its slice of the full frame.

render_rows(renderer)

@spec render_rows(t()) :: [String.t()]

Renders each buffer row to its own ANSI string, in order.

render/1 is Enum.join(render_rows(renderer), "\n") modulo the (currently no-op) font/cursor wrappers -- a property pinned by test. An incremental renderer diffs the grid and re-emits individual rows via this instead of rebuilding the whole frame string.

set_cursor(renderer, position)

Sets the cursor position.

Examples

iex> screen_buffer = ScreenBuffer.new(80, 24)
iex> renderer = Renderer.new(screen_buffer)
iex> renderer = Renderer.set_cursor(renderer, {10, 5})
iex> renderer.cursor
{10, 5}

set_font_settings(renderer, settings)

Updates the font settings.

Examples

iex> screen_buffer = ScreenBuffer.new(80, 24)
iex> renderer = Renderer.new(screen_buffer)
iex> settings = %{family: "Fira Code"}
iex> renderer = Renderer.set_font_settings(renderer, settings)
iex> renderer.font_settings
%{family: "Fira Code"}

set_theme(renderer, theme)

Updates the theme settings.

Examples

iex> screen_buffer = ScreenBuffer.new(80, 24)
iex> renderer = Renderer.new(screen_buffer)
iex> theme = %{foreground: %{default: "#FFF"}}
iex> renderer = Renderer.set_theme(renderer, theme)
iex> renderer.theme
%{foreground: %{default: "#FFF"}}

start_link(opts \\ [])

Starts a new renderer process.

stop(renderer)

Stops the renderer process.