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
@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
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
Gets the current content of the screen buffer.
Parameters
renderer- The renderer to get content fromopts- 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!"}
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{}
Renders the terminal content. The optional opts arguments are currently
unused (accepted for call-site compatibility).
@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.
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.
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}
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"}
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"}}
Starts a new renderer process.
Stops the renderer process.