Module: Terminal

Defined in:
lib/terminal.rb,
lib/terminal/ansi.rb,
lib/terminal/text.rb,
lib/terminal/input.rb,
lib/terminal/shell.rb,
lib/terminal/detect.rb,
lib/terminal/output.rb,
lib/terminal/version.rb,
lib/terminal/input/ansi.rb,
lib/terminal/input/dumb.rb,
lib/terminal/output/ansi.rb,
lib/terminal/output/dumb.rb,
lib/terminal/text/formatter.rb,
lib/terminal/input/key_event.rb,
lib/terminal/text/char_width.rb,
lib/terminal/ansi/named_colors.rb,
lib/terminal/ansi/screen_viewer.rb

Overview

Terminal I/O with ANSI support, BBCode markup, Unicode display width, keyboard/mouse events, and text formatting.

The appropriate output and input modes are selected automatically at load time based on terminal capabilities. Use the class-level methods for all interaction.

Examples:

Formatted output with BBCode

Terminal.puts '[bold green]Success![/]'

Read a key event

event = Terminal.read_key_event
puts "You pressed: #{event.name}"

Execute a shell command

status, out, err = Terminal.sh('ls', '-la')

Defined Under Namespace

Modules: Ansi, Text Classes: KeyEvent

Constant Summary collapse

VERSION =

The version number of the gem.

'1.0.9'

Attributes collapse

Output Attributes collapse

Tool methods collapse

Input methods collapse

Output Methods collapse

Class Attribute Details

.ansi? ⇒ true, false (readonly)

Whether ANSI escape codes are supported.

Returns:

  • (true, false)

See Also:



# File 'lib/terminal/output.rb', line 39

.application ⇒ Symbol? (readonly)

Detect the terminal emulator application.

Known applications: :alacritty, :amiga, :code_edit, :dg_unix, :docker, :fluent, :hpterm, :hyper, :iterm, :kitty, :macos, :mintty, :ms_terminal, :ncr260, :nsterm, :terminator, :terminology, :termite, :vscode, :vt100, :warp, :wyse, :xnuppc

Any unrecognized TERM_PROGRAM value is converted to a sanitized symbol. Returns nil when no terminal can be identified.

Examples:

Terminal.application # => :kitty

Returns:

  • (Symbol, nil) —

    the detected application



65
# File 'lib/terminal.rb', line 65

def application = (@application ||= Detect.application)

.colors ⇒ Integer (readonly)

Number of colors supported by the terminal.

Returns:

  • (Integer) —

    one of 2, 8, 16, 256, or 16777216

See Also:



# File 'lib/terminal/output.rb', line 48

.columns ⇒ Integer

Terminal width in columns.

Returns:

  • (Integer)

See Also:



77
# File 'lib/terminal/output.rb', line 77

def columns = size[1]

.input_mode ⇒ Symbol (readonly)

Detect and return the current input mode.

Examples:

Terminal.input_mode # => :csi_u

Returns:

  • (Symbol) —

    :csi_u, :legacy, :dumb, or :error



# File 'lib/terminal/input.rb', line 10

.output_mode ⇒ :ansi, ... (readonly)

Current output mode.

Returns:

  • (:ansi) —

    All output methods (<<, print, puts) will forward ANSI control codes to the terminal and translate BBCode (see Terminal::Ansi.bbcode).

  • (:dumb) —

    All output methods will not forward ANSI control codes and BBCodes will be removed. The colors method will just return 2 (two).

  • (:error) —

    When the output device signaled an error or was closed, nothing will be written to the terminal.



# File 'lib/terminal/output.rb', line 9

.pos ⇒ Array<Integer, Integer>?

Current cursor position. This is only available when ANSI is supported (ansi? return true).

Returns:

  • (Array<Integer, Integer>, nil) —

    [row, column] or nil if unavailable



# File 'lib/terminal/output.rb', line 87

.resized? ⇒ true, false (readonly)

Whether the terminal has been resized since the last size query.

Returns:

  • (true, false)

See Also:



101
# File 'lib/terminal/output.rb', line 101

def resized? = @size.nil?

.rows ⇒ Integer

Terminal height in rows.

Returns:

  • (Integer)

See Also:



85
# File 'lib/terminal/output.rb', line 85

def rows = size[0]

.size ⇒ Array<Integer, Integer>

The terminal size.

Returns:

  • (Array<Integer, Integer>) —

    [rows, columns]



# File 'lib/terminal/output.rb', line 65

.true_color? ⇒ true, false (readonly)

Whether the terminal supports true color (24-bit, 16.7 million colors).

Returns:

  • (true, false)

See Also:



63
# File 'lib/terminal/output.rb', line 63

def true_color? = (colors == 16_777_216)

.tui? ⇒ true, false (readonly)

Whether the terminal supports full TUI interaction (ANSI output with CSI-u or legacy keyboard input).

Returns:

  • (true, false)

See Also:



# File 'lib/terminal/output.rb', line 30

Class Method Details

.<<(object) ⇒ self

Output an object with BBCode markup processing.

Examples:

Terminal << '[bold]Hello[/bold] World'

Parameters:

  • object (#to_s, nil) —

    the object to output; nil is ignored

Returns:

  • (self)


# File 'lib/terminal/output.rb', line 109

.fputs(*objects, bbcode: true, spaces: true, eol: true, align: nil, width: nil, height: nil, padding: nil, prefix: nil, suffix: nil) ⇒ nil

Formatted output with word-wrapping, alignment, and padding.

Examples:

Terminal.fputs('Hello World', align: :center, width: 40)

Parameters:

  • objects (Array<#to_s>) —

    text to process

  • bbcode (true, false) (defaults to: true) —

    process BBCode markup

  • spaces (true, false) (defaults to: true) —

    preserve whitespace; when false leading/trailing spaces and multiple spaces are collapsed

  • eol (true, false) (defaults to: true) —

    preserve line endings; when false newlines are treated as spaces

  • align (Symbol, nil) (defaults to: nil) —

    text alignment: :left, :right, :center, or nil (no fill)

  • width (#to_i, nil) (defaults to: nil) —

    output line width in columns

  • height (#to_i, nil) (defaults to: nil) —

    number of output lines; negative values take lines from the end; 0 returns [""]

  • padding (#to_i, Array, nil) (defaults to: nil) —

    CSS-style padding

    • 1 value: all sides;
    • 2 values: [vertical, horizontal];
    • 3 values: [top, horizontal, bottom];
    • 4 values: [top, right, bottom, left]
  • prefix (#to_s, nil) (defaults to: nil) —

    string prepended to each line

  • suffix (#to_s, nil) (defaults to: nil) —

    string appended to each line

Returns:

  • (nil)

Raises:

  • (ArgumentError) —

    if width is zero or negative

See Also:



# File 'lib/terminal/output.rb', line 142

.hide_alt_screen ⇒ self

Note:

Reference-counted; safe for nested use.

Switch back from the alternate screen buffer.

Returns:

  • (self)

See Also:



# File 'lib/terminal/output.rb', line 200

.hide_cursor ⇒ self

Note:

Reference-counted; safe for nested use.

Hide the cursor.

Calls are reference-counted — nested calls are safe; the cursor is only hidden on the first call and shown when the last matching show_cursor is called.

Returns:

  • (self)

See Also:



# File 'lib/terminal/output.rb', line 167

.on_key_event(mouse: false, mouse_move: false, focus: false) {|event| ... } ⇒ nil, false

Enter a key event loop, yielding each event to the block.

Enables optional mouse and focus event reporting. The block receives KeyEvent instances until input ends or the block breaks.

Examples:

Terminal.on_key_event(mouse: true) do |event|
  break if event.name == 'Esc'
  puts event.name
end

Parameters:

  • mouse (true, false) (defaults to: false) —

    enable mouse button events

  • mouse_move (true, false) (defaults to: false) —

    enable mouse move events

  • focus (true, false) (defaults to: false) —

    enable terminal focus/unfocus events

Yields:

  • (event) —

    called for each input event

Yield Parameters:

  • event (KeyEvent) —

    the parsed key event

Returns:

  • (nil, false) —

    false on I/O error



# File 'lib/terminal/input.rb', line 25

.on_resize { ... } ⇒ self

Register a callback to be invoked when the terminal is resized.

Examples:

Terminal.on_resize { puts "New size: #{Terminal.size}" }

Yields:

  • called on terminal resize

Returns:

  • (self)


217
218
219
220
# File 'lib/terminal/output.rb', line 217

def on_resize(&block)
  @on_resize = block
  self
end

Print objects to the terminal.

Examples:

Terminal.print('[green]OK[/]')
Terminal.print('press the [red] button', bbcode: false)

Parameters:

  • objects (Array<#to_s>) —

    objects to print

  • bbcode (true, false) (defaults to: true) —

    process BBCode markup

Returns:

  • (nil)


# File 'lib/terminal/output.rb', line 119

.puts(*objects, bbcode: true) ⇒ nil

Print objects to the terminal followed by newlines.

Examples:

Terminal.puts('[bold]Hello[/bold]', '[italic]World[/italic]')

Parameters:

  • objects (Array<#to_s>) —

    objects to print

  • bbcode (true, false) (defaults to: true) —

    process BBCode markup

Returns:

  • (nil)


# File 'lib/terminal/output.rb', line 131

.raw_write(object) ⇒ Integer?

Write raw bytes directly to the terminal without BBCode or ANSI processing.

Parameters:

  • object (#to_s) —

    object to write

Returns:

  • (Integer, nil) —

    bytes written, or nil on error



# File 'lib/terminal/output.rb', line 159

.read_key_event ⇒ KeyEvent, false

Read a single key event (blocking).

Examples:

event = Terminal.read_key_event
puts "You pressed: #{event.name}"

Returns:

  • (KeyEvent, false) —

    the next key event, or false on error



# File 'lib/terminal/input.rb', line 46

.sh(*cmd, env: {}, shell: false, input: nil, **options) ⇒ Array<Process::Status, Array<String>, Array<String>>? .sh(*cmd, env: {}, shell: false, input: nil, **options) {|line, type| ... } ⇒ Process::Status?

Execute a shell command.

Output lines are collected or yielded without their trailing newline.

Overloads:

  • .sh(*cmd, env: {}, shell: false, input: nil, **options) ⇒ Array<Process::Status, Array<String>, Array<String>>?

    Run a command and capture its output.

    Examples:

    status, output, error = Terminal.sh('echo', 'hello')
    output # => ["hello"]

    Parameters:

    • cmd (Array<String>) —

      command and arguments

    • env (Hash) (defaults to: {}) —

      environment variables for the command

    • shell (true, false) (defaults to: false) —

      when true the cmd is executed via the shell, when false, the executable is direct executed (see Process.spawn for this)

    • input (String, IO, Array<String>, Enumerable, nil) (defaults to: nil) —

      data written to the command's standard input

    • options (Hash) —

      passed to Process.spawn (:in, :out, :err are ignored)

    Returns:

    • (Array<Process::Status, Array<String>, Array<String>>) —

      [status, stdout_lines, stderr_lines]

    • (nil) —

      when the command can not be executed

  • .sh(*cmd, env: {}, shell: false, input: nil, **options) {|line, type| ... } ⇒ Process::Status?

    Run a command and stream its output to a block.

    Examples:

    Terminal.sh('make') do |line, type|
      Terminal.puts(type == :error ? "[red]#{line}[/]" : line)
    end

    Parameters:

    • cmd (Array<String>) —

      command and arguments

    • env (Hash) (defaults to: {}) —

      environment variables for the command

    • shell (true, false) (defaults to: false) —

      when true the cmd is executed via the shell, when false, the executable is direct executed (see Process.spawn for this)

    • input (String, IO, Array<String>, Enumerable, nil) (defaults to: nil) —

      data written to the command's standard input

    • options (Hash) —

      passed to Process.spawn (:in, :out, :err are ignored)

    Yields:

    • (line, type) —

      called for each output line

    Yield Parameters:

    • line (String) —

      the output line

    • type (Symbol) —

      :output or :error

    Returns:

    • (Process::Status) —

      the exit status

    • (nil) —

      when the command can not be executed

Raises:

  • (ArgumentError) —

    if no command is given



123
124
125
126
127
128
129
130
# File 'lib/terminal.rb', line 123

def sh(*cmd, **, &)
  raise(ArgumentError, 'command expected') if cmd.empty?
  return Shell.run(*cmd, **, &) if block_given?
  out = []
  err = []
  ret = Shell.run(*cmd, **) { |l, t| (t == :error ? err : out) << l }
  [ret, out, err] if ret
end

.show_alt_screen ⇒ self

Note:

Reference-counted; safe for nested use.

Switch to the alternate screen buffer.

Returns:

  • (self)

See Also:



# File 'lib/terminal/output.rb', line 190

.show_cursor ⇒ self

Note:

Reference-counted; safe for nested use.

Show the cursor.

Returns:

  • (self)

See Also:



# File 'lib/terminal/output.rb', line 181