Terminal
Æsh Readline provides terminal abstraction through the Connection and Terminal interfaces.
TerminalConnection
The standard terminal connection:
import org.aesh.tty.terminal.TerminalConnection;
TerminalConnection connection = new TerminalConnection();
connection.openBlocking(); // Blocking mode
// OR
connection.openNonBlocking(); // Non-blocking modeConnection Interface
Key Methods
Connection connection = new TerminalConnection();
// Terminal information
Device device = connection.device();
Size size = connection.size();
Charset inputEncoding = connection.inputEncoding();
Charset outputEncoding = connection.outputEncoding();
boolean supportsAnsi = connection.supportsAnsi();
// Write output
connection.write("Hello, World!\n");
// Handlers
Consumer<int[]> stdinHandler = connection.getStdinHandler();
connection.setStdinHandler(handler -> { /* process input */ });
Consumer<Size> sizeHandler = connection.getSizeHandler();
connection.setSizeHandler(size -> { /* handle resize */ });
Consumer<Signal> signalHandler = connection.getSignalHandler();
connection.setSignalHandler(signal -> { /* handle signals */ });
// Close
connection.close();
connection.close(exitCode);Raw Mode
Enter raw mode for character-by-character input:
Attributes previousAttributes = connection.enterRawMode();
// ... do work ...
connection.setAttributes(previousAttributes);Terminal Attributes
Control terminal behavior:
Attributes attrs = connection.getAttributes();
// Local flags
attrs.setLocalFlag(Attributes.LocalFlag.ICANON, false); // Disable canonical mode
attrs.setLocalFlag(Attributes.LocalFlag.ECHO, false); // Disable echo
attrs.setLocalFlag(Attributes.LocalFlag.IEXTEN, false); // Disable implementation-defined processing
// Input flags
attrs.setInputFlag(Attributes.InputFlag.IXON, false); // Disable XON/XOFF flow control
// Control characters
attrs.setControlChar(Attributes.ControlChar.VMIN, 1); // Minimum read
attrs.setControlChar(Attributes.ControlChar.VTIME, 0); // Timeout deciseconds
connection.setAttributes(attrs);Terminal Size
Size size = connection.size();
int rows = size.getHeight();
int columns = size.getWidth();Handle resize events:
connection.setSizeHandler(newSize -> {
System.out.println("Terminal resized to: " + newSize.getWidth() + "x" + newSize.getHeight());
});TerminalBuilder
Build custom terminal configurations:
import org.aesh.readline.terminal.TerminalBuilder;
Terminal terminal = TerminalBuilder.builder()
.name("myterminal")
.nativeSignals(true)
.streams(System.in, System.out)
.build();Signal Handling
Handle terminal signals:
connection.setSignalHandler(signal -> {
switch (signal) {
case INT: // Ctrl+C
System.out.println("Interrupt received");
break;
case QUIT: // Ctrl+\
System.out.println("Quit received");
break;
case TSTP: // Ctrl+Z
System.out.println("Suspend received");
break;
case CONT: // Continue after suspend
System.out.println("Continue received");
break;
case WINCH: // Window change
System.out.println("Window changed");
break;
}
});Cursor Position
Get current cursor position:
Point position = connection.getCursorPosition();
int row = position.getRow();
int col = position.getColumn();Device Attributes
Query the terminal for its capabilities using DA1/DA2 escape sequences:
// Query primary device attributes (DA1)
DeviceAttributes da = connection.queryPrimaryDeviceAttributes(500);
if (da != null) {
// Check device class (conformance level)
int deviceClass = da.getDeviceClass(); // 62=VT220, 64=VT420, etc.
// Check feature support
if (da.supportsSixel()) {
System.out.println("Terminal supports Sixel graphics");
}
if (da.supportsAnsiColor()) {
System.out.println("Terminal supports ANSI colors");
}
if (da.supportsMouse()) {
System.out.println("Terminal supports mouse/locator");
}
}
// Query both DA1 and DA2
DeviceAttributes full = connection.queryDeviceAttributes(500);
if (full != null && full.hasDA2()) {
System.out.println("Terminal type: " + full.getTerminalType().getName());
System.out.println("Firmware version: " + full.getFirmwareVersion());
}DeviceAttributes Class
The DeviceAttributes class provides:
- Device class: Conformance level (1=VT100, 62=VT220, 64=VT420)
- Features: Set of supported capabilities (Sixel, ANSI color, mouse, etc.)
- Terminal type: From DA2 (VT100, VT220, VT420, xterm)
- Firmware version: Version number from DA2
// Check if OSC queries are likely supported based on DA1 features
if (da.likelySupportsOscQueries()) {
int[] bgColor = connection.queryBackgroundColor(500);
}Terminal Environment Detection
The TerminalEnvironment class provides centralized detection of terminal type and capabilities:
import org.aesh.terminal.Device;
import org.aesh.terminal.utils.TerminalEnvironment;
TerminalEnvironment env = TerminalEnvironment.getInstance();
// Detect terminal type
Device.TerminalType type = env.getTerminalType();
System.out.println("Terminal: " + type.getIdentifier());
// Check for specific terminals
if (env.isKitty()) {
System.out.println("Running in Kitty");
}
if (env.isJetBrains()) {
System.out.println("Running in JetBrains IDE");
}
// Check multiplexer status
if (env.isInMultiplexer()) {
System.out.println("Running in tmux or screen");
}
// Check OSC support
if (env.supportsOscQueries()) {
System.out.println("OSC queries supported");
}
// Get color depth
ColorDepth depth = env.getDefaultColorDepth();The Device interface methods also use TerminalEnvironment internally:
Device device = connection.device();
// These use TerminalEnvironment
Device.TerminalType type = device.detectTerminalType();
boolean oscSupported = device.supportsOscQueries();
boolean isMultiplexer = device.isMultiplexer();See Terminal Environment for complete documentation.
Image Protocol Detection
Detect the terminal’s inline image support:
// Heuristic detection (fast, no terminal query)
Device device = connection.device();
ImageProtocol protocol = device.getImageProtocol();
// Query-based detection (accurate, uses DA1)
ImageProtocol protocol = connection.queryImageProtocol(500);
switch (protocol) {
case KITTY:
// Kitty, Ghostty, Konsole
break;
case ITERM2:
// iTerm2, WezTerm, VS Code, Mintty
break;
case SIXEL:
// xterm, mlterm, foot, contour
break;
case NONE:
// No inline image support
break;
}The ImageProtocolDetector class combines multiple detection methods:
- Environment variables (KITTY_WINDOW_ID, ITERM_SESSION_ID, etc.)
- Terminal type string (from TERM environment variable)
- DA1 device attributes (authoritative Sixel detection)
OSC Queries
Query the terminal using OSC (Operating System Command) sequences:
// Query background color
int[] bgColor = connection.queryBackgroundColor(500);
if (bgColor != null) {
int r = bgColor[0], g = bgColor[1], b = bgColor[2];
boolean isDark = (r + g + b) / 3 < 128;
}
// Query foreground color
int[] fgColor = connection.queryForegroundColor(500);
// Generic OSC query with custom parser
String result = connection.queryOsc(oscCode, "?", 500, input -> {
// Parse the response
return parseResponse(input);
});OSC Support Detection
// Check if OSC queries are supported
if (connection.supportsOscQueries()) {
// Safe to use OSC queries
}
// More accurate check using DA1 attributes
DeviceAttributes da = connection.queryPrimaryDeviceAttributes(500);
if (connection.supportsOscQueries(da)) {
// DA1 indicates modern terminal features
}