Skip to content

aeshell/aesh-readline

Repository files navigation

Æsh (Another Extendable SHell) Readline

Build Status License

Homepage: aeshell.github.io

Æsh Readline is a library for handling console input with the goal to support most GNU Readline features.

For examples, have a look here: Aesh Examples

Table of Contents

Features

Core Readline

  • Line editing
  • History (search, persistence)
  • Completion
  • Masking
  • Undo and Redo
  • Paste buffer
  • Emacs and Vi editing mode
  • Supports POSIX OS's and Windows
  • Easy to configure (history file & buffer size, edit mode, streams, possible to override terminal implementations, etc)
  • Support standard out and standard error
  • Redirect
  • Alias
  • Pipeline

Terminal Colors and Styling

  • Color Detection - Automatically detect terminal theme (light/dark) and color depth
  • ANSIBuilder - Fluent API for building styled terminal output
  • Semantic Colors - Theme-aware colors for log levels (error, warning, info, debug, trace)
  • Extended Colors - Support for 256-color palette and 24-bit true color (RGB/hex)
  • Color Adaptation - Automatic color downgrading for terminals with limited color support

Terminal Graphics

  • Image Support - Display images in supported terminals (Kitty, iTerm2, Sixel)

Scope

The scope of Æsh Readline is to provide an easy to use Readline library. It is used by the Aesh project.

Connectivity

Æsh Readline supports remote connections via SSH, Telnet, and WebSockets, enabling console applications to run over networks.

How to Build

Æsh Readline uses Maven (https://maven.apache.org/) as its build tool.

Prerequisites

  • Java 8 or higher
  • Maven 3.6+

Building

To build the project:

mvn clean install

To run tests:

mvn test

Getting Started

Here's a simple example to get you started:

import org.aesh.readline.Readline;
import org.aesh.readline.ReadlineBuilder;
import org.aesh.tty.terminal.TerminalConnection;

import java.io.IOException;


public class SimpleExample {

    public static void main(String... args) {
        TerminalConnection connection = new TerminalConnection();
        read(connection, ReadlineBuilder.builder().enableHistory(false).build(), "[aesh@rules]$ ");
        connection.openBlocking();
    }

    private static void read(TerminalConnection connection, Readline readline, String prompt) {
        readline.readline(connection, prompt, input -> {
            if(input != null && input.equals("exit")) {
                connection.write("we're exiting\n");
                connection.close();
            }
            else {
                connection.write("=====> "+input+"\n");
                read(connection, readline, prompt);
            }
        });
    }
}

Terminal Colors

Æsh Readline provides comprehensive terminal color support with automatic theme detection and a fluent API for styled output.

Color Detection

Automatically detect the terminal's color capabilities and theme:

import org.aesh.terminal.utils.TerminalColorCapability;

// Quick detection from environment variables
TerminalColorCapability cap = TerminalColorCapability.detectFromEnvironment();

// Check theme and color depth
if (cap.getTheme().isDark()) {
    // Use light colors for dark backgrounds
}

if (cap.getColorDepth().supportsTrueColor()) {
    // Terminal supports 24-bit RGB colors
}

ANSIBuilder

Use ANSIBuilder for fluent, theme-aware terminal styling:

import org.aesh.terminal.utils.ANSIBuilder;

// Basic usage
String output = ANSIBuilder.builder()
    .bold("Title: ").append("Some text")
    .toString();

// Theme-aware semantic colors
TerminalColorCapability cap = TerminalColorCapability.detectFromEnvironment();
ANSIBuilder builder = ANSIBuilder.builder(cap);

String logLine = builder
    .timestamp("10:30:45").append(" ")
    .error("[ERROR]").append(" ")
    .append("Connection failed")
    .toLine();

Semantic Colors

Theme-aware colors for log levels that automatically adjust to light/dark terminals:

ANSIBuilder builder = ANSIBuilder.builder(cap);

// Log level colors (most to least prominent)
builder.error("Error message");      // Red
builder.warning("Warning message");  // Yellow
builder.success("Success message");  // Green (same as INFO level)
builder.info("Info message");        // Blue
builder.debug("Debug message");      // White/Gray (subdued)
builder.trace("Trace message");      // Gray (least prominent)

// Other semantic colors
builder.timestamp("10:30:45");       // Cyan
builder.message("Highlighted");      // Magenta

Extended Colors

Support for 256-color palette and 24-bit true color:

// 256-color palette
builder.color256(208).append("Orange text");
builder.bg256(17).append("Blue background");

// True color RGB
builder.rgb(255, 87, 51).append("Custom color");
builder.bgRgb(30, 30, 30).append("Dark background");

// Hex colors
builder.hex("#FF5733").append("Coral text");
builder.bgHex("#1E1E1E").append("Dark background");

Custom Color Overrides

Override semantic colors with custom values:

ANSIBuilder builder = ANSIBuilder.builder()
    .errorCode(196)              // 256-color red
    .successHex("#00FF00")       // Hex green
    .timestampRgb(100, 149, 237); // RGB cornflower blue

builder.error("Custom error color");

Terminal Images

Display images in terminals that support graphics protocols (Kitty, iTerm2, Sixel).

Basic Usage

import org.aesh.terminal.utils.TerminalImageBuilder;
import java.nio.file.Path;

// Display an image
String imageData = TerminalImageBuilder.builder()
    .file(Path.of("image.png"))
    .width(40)
    .height(20)
    .build();

connection.write(imageData);

Protocol Detection

// Check which protocol the terminal supports
TerminalGraphicsCapability graphics = TerminalGraphicsDetector.detect(connection);

if (graphics.supportsKitty()) {
    // Use Kitty graphics protocol
} else if (graphics.supportsIterm()) {
    // Use iTerm2 inline images
} else if (graphics.supportsSixel()) {
    // Use Sixel graphics
}

Documentation

For detailed documentation, visit the Æsh Readline Documentation.

Examples

For examples, have a look at Aesh Examples

Keys that are mapped by default in Æsh Readline

Note: C equals Control and M is Meta/Alt

EMACS Mode

  • Move back one char : C-b or left arrow
  • Move forward one char : C-f or right arrow
  • Delete the character left of cursor : backspace
  • Delete the character on cursor : C-d
  • Undo : C-_ or C-x C-u
  • Move to the start of the line : C-a or home
  • Move to the end of the line : C-e or end
  • Move forward a word, where a word is composed of letters and digits : M-f
  • Move backward a word : M-b
  • Previous line : up arrow
  • Next line : down arrow
  • Clear the screen, reprinting the current line at the top : C-l
  • Delete next word to the right of cursor : M-d
  • Complete : tab
  • Kill the text from the current cursor position to the end of the line : C-k
  • Kill from the cursor to the end of the current word, or, if between words, to the end of the next word : M-d
  • Kill from the cursor to the previous whitespace : C-w
  • Yank the most recently killed text back into the buffer at the cursor : C-y
  • Search backward in the history for a particular string : C-r
  • Search forward in the history for a particular string : C-s
  • Switch to VI editing mode: M-C-j

VI Mode

In command mode: About every vi command is supported, here's a few:

  • Move back one char : h
  • Move forward one char : l
  • Delete the character left of cursor : X
  • Delete the character on cursor : x
  • Undo : u
  • Move to the start of the line : 0
  • Move to the end of the line : $
  • Move forward a word, where a word is composed of letters and digits : w
  • Move backward a word : b
  • Previous line : k
  • Next line : n
  • Clear the screen, reprinting the current line at the top : C-l
  • Delete next word to the right of cursor : dw
  • Kill the text from the current cursor position to the end of the line : D and d$
  • Kill from the cursor to the end of the current word, or, if between words, to the end of the next word : db
  • Kill from the cursor to the previous whitespace : dB
  • Yank the most recently killed text back into the buffer at the cursor : p (after cursor), P (before cursor)
  • Add text into yank buffer : y + movement action
  • Enable change mode : c
  • Repeat previous action : .
  • +++ (read a vi manual)

In edit mode:

  • Search backward in the history for a particular string : C-r
  • Search forward in the history for a particular string : C-s
  • Delete the character left of cursor : backspace

Supported runtime properties

  • aesh.terminal : specify Terminal object
  • aesh.editmode : specify either VI or EMACS edit mode
  • aesh.readinputrc : specify if Æsh should read settings from inputrc
  • aesh.inputrc : specify the inputrc file (must exist)
  • aesh.historyfile : specify the history file (must exist)
  • aesh.historypersistent : specify if Æsh should persist history file on exit
  • aesh.historydisabled : specify if history should be disabled
  • aesh.historysize : specify the maximum size of the history file
  • aesh.logging : specify if logging should be enabled
  • aesh.logfile : specify the log file
  • aesh.disablecompletion : specify if completion should be disabled

Contributing

We welcome contributions! Please see our Contributing Guide for details on how to get started.

License

This project is licensed under the Apache License, Version 2.0. See the LICENSE file for details.

About

Java Readline API

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 12