class
Termisu::Terminal
- Termisu::Terminal
- Termisu::Renderer
- Reference
- Object
Overview
High-level terminal interface combining I/O backend, Terminfo, and cell buffer.
Provides a complete terminal UI API including:
- Cell-based rendering with double buffering
- Cursor movement and visibility
- Colors and text attributes
- Alternate screen mode
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.crConstant Summary
-
BSU =
"\e[?2026h" -
Synchronized update escape sequences. Prevents screen tearing by buffering output between BSU and ESU. Supported by: Windows Terminal, Kitty, iTerm2, Wezterm, Alacritty 0.13+, foot, mintty, Ghostty. Unsupported terminals simply ignore these sequences.
-
ESU =
"\e[?2026l" -
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
-
.new(backend : Terminal::Backend = Terminal::Backend.new, terminfo : Terminfo = Terminfo.new, *, sync_updates : Bool = true)
Creates a new terminal.
Instance Method Summary
-
#alternate_screen? : Bool
Returns whether alternate screen mode is active.
-
#background=(color : Color)
Sets the background color with full ANSI-8, ANSI-256, and RGB support.
-
#clear_cells
Clears the cell buffer (fills with default cells).
-
#clear_screen
Clears the screen.
-
#close
Closes the terminal and underlying backend.
-
#current_mode : Terminal::Mode | Nil
Returns the current terminal mode, or nil if not yet set.
-
#disable_enhanced_keyboard
Disables enhanced keyboard protocol.
-
#disable_mouse
Disables mouse input tracking.
-
#disable_raw_mode
Disables raw mode on the terminal.
-
#enable_blink
Enables blink.
-
#enable_bold
Enables bold text.
-
#enable_cursive
Enables italic/cursive text.
-
#enable_dim
Enables dim/faint text.
-
#enable_enhanced_keyboard
Enables enhanced keyboard protocol for disambiguated key reporting.
-
#enable_hidden
Enables hidden/invisible text.
-
#enable_mouse
Enables mouse input tracking.
-
#enable_raw_mode
Enables raw mode on the terminal.
-
#enable_reverse
Enables reverse video.
-
#enable_strikethrough
Enables strikethrough text.
-
#enable_underline
Enables underline.
-
#enhanced_keyboard? : Bool
Returns whether enhanced keyboard protocol is enabled.
-
#enter_alternate_screen
Enters alternate screen mode.
-
#exit_alternate_screen
Exits alternate screen mode.
-
#flush
Delegates flush to backend.
-
#foreground=(color : Color)
Sets the foreground color with full ANSI-8, ANSI-256, and RGB support.
-
#get_cell(x : Int32, y : Int32) : Cell | Nil
Gets a cell at the specified position from the buffer.
-
#hide_cursor
Hides the cursor (rendered on next render()).
-
#infd : Int32
Returns the input file descriptor for Reader.
-
#invalidate_buffer
Invalidates the buffer, forcing a full re-render on next render().
-
#mouse_enabled? : Bool
Returns whether mouse tracking is currently enabled.
-
#move_cursor(x : Int32, y : Int32)
Moves cursor to the specified position.
-
#outfd : Int32
Returns the output file descriptor.
-
#raw_mode? : Bool
Returns whether raw mode is currently enabled.
-
#render
Renders cell buffer changes to the screen.
-
#reset_attributes
Resets all attributes to default.
-
#reset_render_state
Resets the cached render state.
-
#resize_buffer(width : Int32, height : Int32)
Resizes the buffer to new dimensions.
-
#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.
-
#set_cursor(x : Int32, y : Int32)
Sets cursor position in the buffer and makes it visible.
-
#set_mode(mode : Terminal::Mode)
Sets terminal to specific mode using Terminal::Mode flags.
-
#show_cursor
Shows the cursor at current position (rendered on next render()).
-
#size : Tuple(Int32, Int32)
Delegates size to backend.
-
#sync
Forces a full redraw of all cells.
-
#sync_updates=(sync_updates : Bool)
Sets whether synchronized updates are enabled.
-
#sync_updates? : Bool
Returns whether synchronized updates are enabled.
-
#with_cbreak_mode(preserve_screen : Bool = true, &)
Executes a block with cbreak mode.
-
#with_cooked_mode(preserve_screen : Bool = false, &)
Executes a block with cooked (shell-like) mode.
-
#with_mode(mode : Terminal::Mode, preserve_screen : Bool = false, &)
Executes a block with specific terminal mode, restoring previous mode after.
-
#with_password_mode(preserve_screen : Bool = true, &)
Executes a block with password input mode.
-
#with_raw_mode(&)
Executes a block with raw mode enabled, ensuring cleanup.
-
#write(data : String)
Delegates write to backend.
-
#write_hide_cursor
Writes hide cursor escape sequence immediately.
-
#write_show_cursor
Writes show cursor escape sequence immediately.
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
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)sync_updates- Enable DEC mode 2026 synchronized updates (default: true)
Instance Method Detail
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.
Clears the cell buffer (fills with default cells).
Call render() to display changes on screen.
Clears the screen.
Writes the clear screen escape sequence immediately and flushes. Also resets cached render state since screen content is cleared.
Returns the current terminal mode, or nil if not yet set.
Delegates to underlying Backend instance.
Disables enhanced keyboard protocol.
Returns to legacy keyboard mode where Tab/Ctrl+I, Enter/Ctrl+M, etc. are indistinguishable.
Enables italic/cursive text.
Caches attribute state to avoid redundant escape sequences.
Enables dim/faint text.
Caches attribute state to avoid redundant escape sequences.
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
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
Enables reverse video.
Caches attribute state to avoid redundant escape sequences.
Enables strikethrough text.
Caches attribute state to avoid redundant escape sequences.
Enables underline.
Caches attribute state to avoid redundant escape sequences.
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.
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.
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.
Gets a cell at the specified position from the buffer.
Returns nil if coordinates are out of bounds.
Invalidates the buffer, forcing a full re-render on next render().
Call this after the terminal screen has been cleared externally. Unlike sync(), this doesn't render immediately - it marks the buffer so the next render() call will redraw everything.
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)
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.
When sync_updates is enabled, wraps the render in DEC mode 2026 sequences (BSU/ESU) to prevent screen tearing during rapid updates.
Resets all attributes to default.
Also clears cached color/attribute state since reset affects all styling.
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
Resizes the buffer to new dimensions.
Preserves existing content where possible.
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.
Sets cursor position in the buffer and makes it visible.
Coordinates are clamped to buffer bounds. Call render() to display the cursor on screen.
Sets terminal to specific mode using Terminal::Mode flags.
Updates raw_mode_enabled tracking based on whether mode is raw. Does not handle screen or cursor transitions - use with_mode for that.
Parameters:
- mode: Terminal::Mode flags specifying desired behavior
Example:
terminal.set_mode(Terminal::Mode.cooked)
terminal.set_mode(Terminal::Mode.raw)
ameba:disable Naming/AccessorMethodName
Forces a full redraw of all cells.
Useful after terminal resize or screen corruption.
When sync_updates is enabled, wraps the sync in DEC mode 2026 sequences (BSU/ESU) to prevent screen tearing during the full redraw.
Sets whether synchronized updates are enabled.
Can be toggled at runtime. Set to false for debugging or compatibility with terminals that misbehave with sync sequences.
Returns whether synchronized updates are enabled.
When enabled, render operations are wrapped in BSU/ESU sequences to prevent screen tearing. Enabled by default.
Executes a block with cbreak mode.
Cbreak mode provides character-by-character input with echo and signal handling. Useful for interactive prompts where you want immediate response but still show typed characters.
By default, preserves alternate screen since cbreak is typically used within a TUI context.
Example:
terminal.with_cbreak_mode do
print "Press any key: "
key = STDIN.read_char
end
Executes a block with cooked (shell-like) mode.
Cooked mode enables canonical input, echo, and signal handling - ideal for shell-out operations where the subprocess needs full terminal control.
By default, exits alternate screen to show the normal terminal, then re-enters alternate screen after the block.
Example:
terminal.with_cooked_mode do
system("vim file.txt")
end
Executes a block with specific terminal mode, restoring previous mode after.
This is the recommended way to temporarily switch modes for operations like shell-out or password input. Handles:
- Mode switching via Backend
- Alternate screen exit/entry based on preserve_screen parameter
- Cursor visibility (shown for user-interactive modes)
Parameters:
- mode: Terminal::Mode to use within the block
- preserve_screen: If false (default) and mode is canonical, exits alternate screen during block. If true, stays in alternate screen.
Example:
terminal.with_mode(Terminal::Mode.cooked) do
system("vim file.txt")
end
# Previous mode and screen state restored
Executes a block with password input mode.
Password mode enables canonical (line-buffered) input with signal handling but disables echo. Perfect for secure password entry.
By default, preserves alternate screen since password prompts often appear within a TUI context.
Example:
terminal.with_password_mode do
print "Password: "
password = gets
end
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.
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.