module RatatuiRuby
Main entry point for the library.
Terminal UIs require low-level control using C/Rust and high-level abstraction in Ruby.
This module bridges the gap. It provides the native methods to initialize the terminal, handle raw mode, and render the widget tree.
Use ‘RatatuiRuby.run` to start your application.
Constants
- VERSION
-
The version of the ratatui_ruby gem. See semver.org/spec/v2.0.0.html
Attributes
:attr_accessor: experimental_warnings Whether to show warnings when using experimental features (default: true).
Public Class Methods
Source
# File lib/ratatui_ruby.rb, line 253 def self.draw(tree = nil, &block) if tree && block raise ArgumentError, "Cannot provide both a tree and a block to draw" end unless tree || block raise ArgumentError, "Must provide either a tree or a block to draw" end if tree _draw(tree) else _draw(&block) end end
Draws the given UI node tree to the terminal.
TUI applications need to render widgets to the screen. Rendering could happen all at once with a pre-built tree, or incrementally with direct frame access.
This method handles both. Pass a tree for declarative rendering, or pass a block to manipulate the frame directly. The block receives a {Frame} object for imperative drawing.
- tree
-
A widget tree (
Widgets::Paragraph,Layout::Layout, etc.) to render. Optional if a block is given.
Examples
Legacy declarative style (tree-based):
RatatuiRuby.draw(Widgets::Paragraph.new(text: "Hello"))
New imperative style (block-based):
RatatuiRuby.draw do |frame| frame.render_widget(Widgets::Paragraph.new(text: "Hello"), frame.area) end
Source
# File lib/ratatui_ruby.rb, line 368 def self.get_cell_at(x, y) raw = _get_cell_at(x, y) Buffer::Cell.new( char: raw["char"], fg: raw["fg"], bg: raw["bg"], modifiers: raw["modifiers"] || [] ) end
Inspects the terminal buffer at specific coordinates.
When writing tests, you need to verify that your widget drew the correct characters and styles. This method provides deep inspection of the cell’s state (symbol, colors, modifiers).
Returns a {Buffer::Cell} object.
Values depend on what the backend has rendered. If nothing has been rendered to a cell, it may contain defaults (empty symbol, nil colors).
Example
cell = RatatuiRuby.get_cell_at(10, 5) expect(cell.symbol).to eq("X") expect(cell.fg).to eq(:red) expect(cell).to be_bold
Source
# File lib/ratatui_ruby.rb, line 119 def self.init_terminal(focus_events: true, bracketed_paste: true) if @tui_session_active raise Error::Invariant, "Cannot initialize terminal: TUI session already active" end @tui_session_active = true _init_terminal(focus_events, bracketed_paste) end
Initializes the terminal for TUI mode. Enters alternate screen and enables raw mode.
- focus_events
-
whether to enable focus gain/loss events (default: true).
- bracketed_paste
-
whether to enable bracketed paste mode (default: true).
Source
# File lib/ratatui_ruby.rb, line 216 def self.init_test_terminal(width, height) if @tui_session_active raise Error::Invariant, "Cannot initialize terminal: TUI session already active" end @tui_session_active = true _init_test_terminal(width, height) end
Initializes a test terminal for unit testing. Sets session active state like init_terminal.
- width
-
Integer width of the test terminal.
- height
-
Integer height of the test terminal.
Source
# File lib/ratatui_ruby.rb, line 180
Injects a mock event into the event queue for testing purposes.
- event_type
-
“key” or “mouse”
- data
-
a Hash containing event data
inject_test_event("key", { code: "a" })
(Native method implemented in Rust)
Source
# File lib/ratatui_ruby.rb, line 293 def self.poll_event(timeout: 0.016) raise ArgumentError, "timeout must be non-negative" if timeout && timeout < 0 raw = _poll_event(timeout) return Event::None.new.freeze if raw.nil? case raw[:type] when :key Event::Key.new( code: raw[:code], modifiers: (raw[:modifiers] || []).freeze, kind: raw[:kind] || :standard ).freeze when :mouse Event::Mouse.new( kind: raw[:kind].to_s, x: raw[:x], y: raw[:y], button: raw[:button].to_s, modifiers: (raw[:modifiers] || []).freeze ).freeze when :resize Event::Resize.new(width: raw[:width], height: raw[:height]).freeze when :paste Event::Paste.new(content: raw[:content]).freeze when :focus_gained Event::FocusGained.new.freeze when :focus_lost Event::FocusLost.new.freeze else # Fallback for unknown events, though ideally we cover them all nil end end
Checks for user input.
Interactive apps must respond to input. Loops need to poll without burning CPU.
This method checks for an event. It returns the event if one is found. It returns {RatatuiRuby::Event::None} if the timeout expires.
- timeout
-
Float seconds to wait (default: 0.016). Pass
nilto block indefinitely (wait forever). Pass0.0for a non-blocking check.
Examples
# Standard loop (approx 60 FPS) event = RatatuiRuby.poll_event # Block until event (pauses execution) event = RatatuiRuby.poll_event(timeout: nil) # Non-blocking check (returns immediately) event = RatatuiRuby.poll_event(timeout: 0.0)
Source
# File lib/ratatui_ruby.rb, line 172 def self.restore_terminal _restore_terminal ensure @tui_session_active = false flush_warnings end
Restores the terminal to its original state. Leaves alternate screen and disables raw mode. Also flushes any deferred warnings that were queued during the session.
Source
# File lib/ratatui_ruby.rb, line 344 def self.run(focus_events: true, bracketed_paste: true) init_terminal(focus_events:, bracketed_paste:) yield TUI.new ensure restore_terminal end
Starts the TUI application lifecycle.
Managing generic setup/teardown (raw mode, alternate screen) manualy is error-prone. If your app crashes, the terminal might be left in a broken state.
This method handles the safety net. It initializes the terminal, yields a {TUI}, and ensures the terminal state is restored even if exceptions occur.
Example
RatatuiRuby.run(focus_events: false) do |tui| tui.draw(tui.paragraph(text: "Hi")) sleep 1 end
Source
# File lib/ratatui_ruby.rb, line 147 def self.terminal_active? @tui_session_active end
Whether a TUI session is currently active.
Writing to stdout/stderr during a TUI session corrupts the display. Use this to defer logging, warnings, or debug output until after the session ends.
Example
def log(message) if RatatuiRuby.terminal_active? @deferred_logs << message else puts message end end
Source
# File lib/ratatui_ruby.rb, line 195 def self.warn_experimental_feature(feature_name) return unless experimental_warnings @warned_features ||= {} return if @warned_features[feature_name] message = "WARNING: #{feature_name} is an experimental feature and may change in future versions. Disable this warning with RatatuiRuby.experimental_warnings = false." if terminal_active? queue_warning(message) else warn message end @warned_features[feature_name] = true end
Warns about usage of an experimental feature unless warnings are suppressed.
- feature_name
-
String name of the feature (e.g., “Paragraph#line_count”)
This warns only once per feature name per session.