Prompt

The Prompt class represents the prompt displayed to users before input. It supports simple text prompts, styled prompts with colors, and masked input for passwords.

Overview

A prompt is displayed each time the shell waits for user input. Æsh Readline provides flexible prompt configuration:

// Simple string prompt
Prompt prompt = new Prompt("$ ");

// Prompt with mask character for passwords
Prompt prompt = new Prompt("Password: ", '*');

// Styled prompt with colors
Prompt prompt = new Prompt(new TerminalString("[user@host]$ ", 
        new TerminalColor(Color.GREEN, Color.DEFAULT)));

Constructors

Basic Prompt

// Simple text prompt
Prompt prompt = new Prompt("myapp> ");

Prompt with Mask

Used for password input where characters should be hidden:

// Characters are replaced with '*'
Prompt prompt = new Prompt("Password: ", '*');

// Characters are hidden (no echo)
Prompt prompt = new Prompt("Secret: ", '\0');

Prompt with TerminalString

For styled prompts with colors:

TerminalString styledPrompt = new TerminalString(
        "[admin]# ",
        new TerminalColor(Color.RED, Color.DEFAULT),
        CharacterType.BOLD
);
Prompt prompt = new Prompt(styledPrompt);

Prompt with Multiple TerminalStrings

For complex multi-part prompts:

List<TerminalString> parts = Arrays.asList(
        new TerminalString("[", new TerminalColor(Color.WHITE, Color.DEFAULT)),
        new TerminalString("user", new TerminalColor(Color.GREEN, Color.DEFAULT)),
        new TerminalString("@", new TerminalColor(Color.WHITE, Color.DEFAULT)),
        new TerminalString("host", new TerminalColor(Color.BLUE, Color.DEFAULT)),
        new TerminalString("]$ ", new TerminalColor(Color.WHITE, Color.DEFAULT))
);
Prompt prompt = new Prompt(parts);

Prompt Properties

PropertyTypeDescription
promptStringThe prompt text
maskCharacterMask character for input (null if no masking)
ansiStringTerminalStringStyled prompt string
ansiStringsList<TerminalString>Multiple styled prompt parts

Methods

getPromptAsString()

Returns the prompt text without ANSI codes:

Prompt prompt = new Prompt("[user]$ ");
String text = prompt.getPromptAsString(); // "[user]$ "

getMask()

Returns the mask character, or null if no masking:

Prompt prompt = new Prompt("Password: ", '*');
Character mask = prompt.getMask(); // '*'

isMasking()

Returns true if the prompt uses input masking:

Prompt prompt = new Prompt("Password: ", '*');
boolean masking = prompt.isMasking(); // true

hasANSI()

Returns true if the prompt uses ANSI styling:

Prompt prompt = new Prompt(new TerminalString("$ ", Color.GREEN));
boolean hasAnsi = prompt.hasANSI(); // true

copy()

Creates a copy of the prompt:

Prompt original = new Prompt("$ ");
Prompt copy = original.copy();

Using Prompts

With Readline

Readline readline = ReadlineBuilder.builder().build();

Prompt prompt = new Prompt("myapp> ");
readline.readline(connection, prompt, input -> {
    // Handle input
});

With AeshConsoleRunner

AeshConsoleRunner.builder()
        .command(MyCommand.class)
        .prompt("[myshell]$ ")  // Simple string
        .start();

// Or with a Prompt object
Prompt prompt = new Prompt(new TerminalString("$ ", Color.CYAN));
AeshConsoleRunner.builder()
        .command(MyCommand.class)
        .prompt(prompt)
        .start();

Dynamic Prompts

Create prompts that change based on context:

public class DynamicPromptShell {
    private String currentDirectory = "/home/user";
    private String username = "user";
    
    public void start() {
        AeshConsoleRunner.builder()
                .command(CdCommand.class)
                .prompt(this::createPrompt)
                .addExitCommand()
                .start();
    }
    
    private Prompt createPrompt() {
        String promptText = String.format("[%s@%s]$ ", username, currentDirectory);
        return new Prompt(new TerminalString(promptText, Color.GREEN));
    }
    
    public void setCurrentDirectory(String dir) {
        this.currentDirectory = dir;
    }
}

Styled Prompts

Colors

// Foreground color only
new TerminalString("$ ", new TerminalColor(Color.GREEN, Color.DEFAULT))

// Foreground and background
new TerminalString("$ ", new TerminalColor(Color.WHITE, Color.BLUE))

// Using RGB colors (24-bit)
new TerminalString("$ ", new TerminalColor(new Color(255, 100, 50), Color.DEFAULT))

Text Styles

// Bold text
new TerminalString("$ ", Color.DEFAULT, CharacterType.BOLD)

// Italic text
new TerminalString("$ ", Color.DEFAULT, CharacterType.ITALIC)

// Underlined text
new TerminalString("$ ", Color.DEFAULT, CharacterType.UNDERLINE)

// Combined styles
new TerminalString("$ ", 
        new TerminalColor(Color.RED, Color.DEFAULT),
        CharacterType.BOLD,
        CharacterType.UNDERLINE)

Multi-Part Styled Prompts

List<TerminalString> promptParts = Arrays.asList(
        // Username in green
        new TerminalString(username, new TerminalColor(Color.GREEN, Color.DEFAULT)),
        // Separator
        new TerminalString(":", Color.DEFAULT),
        // Directory in blue
        new TerminalString(currentDir, new TerminalColor(Color.BLUE, Color.DEFAULT), CharacterType.BOLD),
        // Prompt symbol based on user type
        new TerminalString(isRoot ? "# " : "$ ", Color.DEFAULT)
);
Prompt prompt = new Prompt(promptParts);

Password Input

Basic Password Prompt

// Reading password in a command
@Override
public CommandResult execute(CommandInvocation invocation) throws InterruptedException {
    Shell shell = invocation.getShell();
    
    // Password input with asterisk mask
    String password = shell.readLine(new Prompt("Password: ", '*'));
    
    // Authenticate...
    return CommandResult.SUCCESS;
}

Hidden Input (No Echo)

// Use null character for completely hidden input
Prompt hiddenPrompt = new Prompt("API Key: ", '\0');
String apiKey = shell.readLine(hiddenPrompt);

Confirmation Pattern

@Override
public CommandResult execute(CommandInvocation invocation) throws InterruptedException {
    Shell shell = invocation.getShell();
    
    // Get password
    String password = shell.readLine(new Prompt("Enter new password: ", '*'));
    String confirm = shell.readLine(new Prompt("Confirm password: ", '*'));
    
    if (!password.equals(confirm)) {
        invocation.println("Passwords do not match!");
        return CommandResult.FAILURE;
    }
    
    // Save password...
    invocation.println("Password updated successfully.");
    return CommandResult.SUCCESS;
}

Complete Example

import org.aesh.readline.*;
import org.aesh.readline.terminal.formatting.*;
import org.aesh.terminal.Connection;
import java.util.Arrays;
import java.util.List;

public class StyledPromptExample {
    
    public static void main(String[] args) {
        Connection connection = /* obtain connection */;
        Readline readline = ReadlineBuilder.builder().build();
        
        // Create a fancy prompt
        Prompt prompt = createFancyPrompt("user", "/home/user");
        
        readline.readline(connection, prompt, input -> {
            if (input != null && !input.trim().isEmpty()) {
                System.out.println("You entered: " + input);
            }
            
            // Continue reading
            readline.readline(connection, prompt, this);
        });
    }
    
    private static Prompt createFancyPrompt(String user, String directory) {
        List<TerminalString> parts = Arrays.asList(
                // Opening bracket
                new TerminalString("[", 
                        new TerminalColor(Color.WHITE, Color.DEFAULT)),
                
                // Username in green bold
                new TerminalString(user, 
                        new TerminalColor(Color.GREEN, Color.DEFAULT),
                        CharacterType.BOLD),
                
                // @ symbol
                new TerminalString("@", 
                        new TerminalColor(Color.WHITE, Color.DEFAULT)),
                
                // Hostname in cyan
                new TerminalString("localhost", 
                        new TerminalColor(Color.CYAN, Color.DEFAULT)),
                
                // Space and directory in blue
                new TerminalString(" " + shortenPath(directory), 
                        new TerminalColor(Color.BLUE, Color.DEFAULT)),
                
                // Closing bracket and prompt symbol
                new TerminalString("]$ ", 
                        new TerminalColor(Color.WHITE, Color.DEFAULT))
        );
        
        return new Prompt(parts);
    }
    
    private static String shortenPath(String path) {
        // Replace home directory with ~
        String home = System.getProperty("user.home");
        if (path.startsWith(home)) {
            return "~" + path.substring(home.length());
        }
        return path;
    }
}

Git-Style Prompt

Create a prompt that shows git branch information:

public class GitPrompt {
    
    public Prompt create() {
        String branch = getGitBranch();
        String directory = getCurrentDirectory();
        
        List<TerminalString> parts = new ArrayList<>();
        
        // Directory in blue
        parts.add(new TerminalString(directory + " ", 
                new TerminalColor(Color.BLUE, Color.DEFAULT)));
        
        // Git branch if available
        if (branch != null) {
            parts.add(new TerminalString("(", Color.DEFAULT));
            parts.add(new TerminalString(branch, 
                    new TerminalColor(Color.MAGENTA, Color.DEFAULT)));
            parts.add(new TerminalString(") ", Color.DEFAULT));
        }
        
        // Prompt symbol
        parts.add(new TerminalString("$ ", Color.DEFAULT));
        
        return new Prompt(parts);
    }
    
    private String getGitBranch() {
        try {
            Process process = Runtime.getRuntime()
                    .exec(new String[]{"git", "branch", "--show-current"});
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(process.getInputStream()));
            String branch = reader.readLine();
            process.waitFor();
            return process.exitValue() == 0 ? branch : null;
        } catch (Exception e) {
            return null;
        }
    }
    
    private String getCurrentDirectory() {
        return System.getProperty("user.dir");
    }
}

Best Practices

  1. Keep prompts short - Long prompts reduce the space available for user input.

  2. Use colors meaningfully - Use colors to convey information (e.g., green for normal, red for root).

  3. Always mask passwords - Never echo password input to the terminal.

  4. Test color fallbacks - Ensure prompts are readable when colors are not supported.

  5. Consider accessibility - Don’t rely solely on color to convey information.

// Good: Information conveyed by text AND color
new TerminalString("[admin]# ", new TerminalColor(Color.RED, Color.DEFAULT))

// Bad: Information only conveyed by color
new TerminalString("$ ", new TerminalColor(Color.RED, Color.DEFAULT))
  1. Use dynamic prompts sparingly - Regenerating complex prompts on every input can impact performance.