class Termisu::Terminal

Overview

High-level terminal interface combining I/O backend, Terminfo, and cell buffer.

Provides a complete terminal UI API including:

Example:

terminal = Termisu::Terminal.new
terminal.enable_raw_mode
terminal.enter_alternate_screen

terminal.set_cell(10, 5, 'H', fg: Color.red)
terminal.set_cell(11, 5, 'i', fg: Color.green)
terminal.set_cursor(12, 5)
terminal.render

terminal.exit_alternate_screen
terminal.close

Defined in:

termisu/terminal.cr

Constant Summary

KITTY_KEYBOARD_DISABLE = "\e[<u"
KITTY_KEYBOARD_ENABLE = "\e[>1u"

Enhanced keyboard protocol escape sequences. These protocols disambiguate keys that normally send the same bytes (e.g., Tab vs Ctrl+I, Enter vs Ctrl+M).

Kitty keyboard protocol (most comprehensive): https://sw.kovidgoyal.net/kitty/keyboard-protocol/ Flags: 1=disambiguate, 2=report_event_types, 4=report_alternate_keys 8=report_all_keys, 16=report_text

KITTY_KEYBOARD_QUERY = "\e[?u"
Log = Termisu::Logs::Terminal
MODIFY_OTHER_KEYS_DISABLE = "\e[>4;0m"
MODIFY_OTHER_KEYS_ENABLE = "\e[>4;2m"

modifyOtherKeys (xterm, widely supported): Mode 2 reports modified keys as CSI 27 ; modifier ; keycode ~

MOUSE_DISABLE_NORMAL = "\e[?1000l"
MOUSE_DISABLE_SGR = "\e[?1006l"
MOUSE_ENABLE_NORMAL = "\e[?1000h"

Mouse protocol escape sequences. Using CSI ? sequences for xterm-compatible mouse tracking.

MOUSE_ENABLE_SGR = "\e[?1006h"

Constructors

Instance Method Summary

Instance methods inherited from class Termisu::Renderer

background=(color : Color) background=, close close, enable_blink enable_blink, enable_bold enable_bold, enable_cursive enable_cursive, enable_dim enable_dim, enable_hidden enable_hidden, enable_reverse enable_reverse, enable_strikethrough enable_strikethrough, enable_underline enable_underline, flush flush, foreground=(color : Color) foreground=, move_cursor(x : Int32, y : Int32) move_cursor, reset_attributes reset_attributes, size : Tuple(Int32, Int32) size, write(data : String) write, write_hide_cursor write_hide_cursor, write_show_cursor write_show_cursor

Constructor Detail

def self.new(backend : Terminal::Backend = Terminal::Backend.new, terminfo : Terminfo = Terminfo.new) #

Creates a new terminal.

Parameters:

  • backend - Terminal::Backend instance for I/O operations (default: Terminal::Backend.new)
  • terminfo - Terminfo instance for capability strings (default: Terminfo.new)

[View source]

Instance Method Detail

def alternate_screen? : Bool #

Returns whether alternate screen mode is active.


[View source]
def background=(color : Color) #

Sets the background color with full ANSI-8, ANSI-256, and RGB support.

Caches the color to avoid redundant escape sequences when called repeatedly with the same color.


[View source]
def clear_cells #

Clears the cell buffer (fills with default cells).

Call render() to display changes on screen.


[View source]
def clear_screen #

Clears the screen.

Writes the clear screen escape sequence immediately and flushes. Also resets cached render state since screen content is cleared.


[View source]
def close #

Closes the terminal and underlying backend.


[View source]
def disable_enhanced_keyboard #

Disables enhanced keyboard protocol.

Returns to legacy keyboard mode where Tab/Ctrl+I, Enter/Ctrl+M, etc. are indistinguishable.


[View source]
def disable_mouse #

Disables mouse input tracking.

Disables both SGR and normal mouse protocols.


[View source]
def disable_raw_mode #

Disables raw mode on the terminal.


[View source]
def enable_blink #

Enables blink.

Caches attribute state to avoid redundant escape sequences.


[View source]
def enable_bold #

Enables bold text.

Caches attribute state to avoid redundant escape sequences.


[View source]
def enable_cursive #

Enables italic/cursive text.

Caches attribute state to avoid redundant escape sequences.


[View source]
def enable_dim #

Enables dim/faint text.

Caches attribute state to avoid redundant escape sequences.


[View source]
def enable_enhanced_keyboard #

Enables enhanced keyboard protocol for disambiguated key reporting.

This enables the Kitty keyboard protocol (if supported) and falls back to modifyOtherKeys. Enhanced mode allows distinguishing between keys that normally send the same bytes:

  • Tab vs Ctrl+I
  • Enter vs Ctrl+M
  • Backspace vs Ctrl+H

Not all terminals support these protocols. Unsupported terminals will simply ignore the escape sequences and continue with legacy behavior.

Example:

terminal.enable_enhanced_keyboard
# Now Ctrl+I and Tab are distinguishable
terminal.disable_enhanced_keyboard # When done

[View source]
def enable_hidden #

Enables hidden/invisible text.

Caches attribute state to avoid redundant escape sequences.


[View source]
def enable_mouse #

Enables mouse input tracking.

Enables SGR extended mouse protocol (mode 1006) for better coordinate support and unambiguous button detection. Falls back to normal mode (1000) on older terminals that don't support SGR.

Example:

terminal.enable_mouse
# Now mouse events will be reported via poll_event
terminal.disable_mouse # When done

[View source]
def enable_raw_mode #

Enables raw mode on the terminal.


[View source]
def enable_reverse #

Enables reverse video.

Caches attribute state to avoid redundant escape sequences.


[View source]
def enable_strikethrough #

Enables strikethrough text.

Caches attribute state to avoid redundant escape sequences.


[View source]
def enable_underline #

Enables underline.

Caches attribute state to avoid redundant escape sequences.


[View source]
def enhanced_keyboard? : Bool #

Returns whether enhanced keyboard protocol is enabled.


[View source]
def enter_alternate_screen #

Enters alternate screen mode.

Switches to alternate screen buffer, clears the screen, enters keypad mode, and hides cursor. Also resets cached render state since we're entering a fresh screen.


[View source]
def exit_alternate_screen #

Exits alternate screen mode.

Shows cursor, exits keypad mode, and returns to main screen buffer. Also resets cached render state since we're returning to the main screen which may have different state.


[View source]
def flush #

Delegates flush to backend.


[View source]
def foreground=(color : Color) #

Sets the foreground color with full ANSI-8, ANSI-256, and RGB support.

Caches the color to avoid redundant escape sequences when called repeatedly with the same color.


[View source]
def get_cell(x : Int32, y : Int32) : Cell | Nil #

Gets a cell at the specified position from the buffer.

Returns nil if coordinates are out of bounds.


[View source]
def hide_cursor #

Hides the cursor (rendered on next render()).


[View source]
def infd : Int32 #

Returns the input file descriptor for Reader.


[View source]
def mouse_enabled? : Bool #

Returns whether mouse tracking is currently enabled.


[View source]
def move_cursor(x : Int32, y : Int32) #

Moves cursor to the specified position.

Uses the terminfo cup capability with tparm processing for proper terminal-specific cursor addressing. The cup capability handles the 0-to-1 based coordinate conversion via the %i operation.

Parameters:

  • x: Column position (0-based)
  • y: Row position (0-based)

[View source]
def outfd : Int32 #

Returns the output file descriptor.


[View source]
def raw_mode? : Bool #

Returns whether raw mode is currently enabled.


[View source]
def render #

Renders cell buffer changes to the screen.

Only cells that have changed since the last render are redrawn (diff-based). This is more efficient than full redraws for partial updates.


[View source]
def reset_attributes #

Resets all attributes to default.

Also clears cached color/attribute state since reset affects all styling.


[View source]
def reset_render_state #

Resets the cached render state.

Call this when the terminal state becomes unknown (e.g., after external programs have modified the terminal, or after errors). This forces the next color/attribute calls to emit escape sequences even if the cached values match.

The following operations automatically reset render state:

  • enter_alternate_screen
  • exit_alternate_screen
  • clear_screen
  • reset_attributes

[View source]
def resize_buffer(width : Int32, height : Int32) #

Resizes the buffer to new dimensions.

Preserves existing content where possible.


[View source]
def set_cell(x : Int32, y : Int32, ch : Char, fg : Color = Color.white, bg : Color = Color.default, attr : Attribute = Attribute::None) : Bool #

Sets a cell at the specified position in the buffer.

Parameters:

  • x: Column position (0-based)
  • y: Row position (0-based)
  • ch: Character to display
  • fg: Foreground color (default: white)
  • bg: Background color (default: default terminal color)
  • attr: Text attributes (default: None)

Returns false if coordinates are out of bounds. Call render() to display changes on screen.


[View source]
def set_cursor(x : Int32, y : Int32) #

Sets cursor position in the buffer and makes it visible.

Coordinates are clamped to buffer bounds. Call render() to display the cursor on screen.


[View source]
def show_cursor #

Shows the cursor at current position (rendered on next render()).


[View source]
def size : Tuple(Int32, Int32) #

Delegates size to backend.


[View source]
def sync #

Forces a full redraw of all cells.

Useful after terminal resize or screen corruption.


[View source]
def with_raw_mode(&) #

Executes a block with raw mode enabled, ensuring cleanup.


[View source]
def write(data : String) #

Delegates write to backend.


[View source]
def write_hide_cursor #

Writes hide cursor escape sequence immediately.

Caches visibility state to avoid redundant escape sequences. Note: This is part of the Renderer interface, called by Buffer. For buffer-based cursor control, use hide_cursor instead.


[View source]
def write_show_cursor #

Writes show cursor escape sequence immediately.

Caches visibility state to avoid redundant escape sequences. Note: This is part of the Renderer interface, called by Buffer. For buffer-based cursor control, use show_cursor instead.


[View source]