Renderers

Renderers customize how option values are displayed in help text and output.

OptionRenderer Interface

public interface OptionRenderer<T extends ParsedOption> {
    String render(T option);
}

Custom Value Display

Customize how sensitive values are displayed:

public class PasswordRenderer implements OptionRenderer<ProcessedOption> {

    @Override
    public String render(ProcessedOption option) {
        return "******** (password hidden)";
    }
}

Usage:

@CommandDefinition(name = "login")
public class LoginCommand implements Command<CommandInvocation> {

    @Option(
        name = "username",
        description = "Username"
    )
    private String username;

    @Option(
        name = "password",
        renderer = PasswordRenderer.class,
        description = "Password"
    )
    private String password;

    @Override
    public CommandResult execute(CommandInvocation invocation) {
        // Password is displayed normally here, only hidden in help
        return CommandResult.SUCCESS;
    }
}

Colorized Output

import org.aesh.readline.terminal.formatting.TerminalColor;
import org.aesh.readline.terminal.formatting.TerminalString;
import org.aesh.readline.terminal.formatting.TerminalTextStyle;
import org.aesh.readline.terminal.formatting.CharacterType;
import org.aesh.readline.terminal.formatting.Color;

public class ColorizedRenderer implements OptionRenderer<ProcessedOption> {

    @Override
    public String render(ProcessedOption option) {
        TerminalString colorized = new TerminalString(
            option.getValue(),
            new TerminalColor(Color.CYAN, Color.DEFAULT),
            new TerminalTextStyle(CharacterType.BOLD)
        );
        return colorized.toString();
    }
}

Theme-Aware Rendering

For colors that adapt to the terminal’s light or dark theme, use the semantic color methods with detected terminal capabilities:

import org.aesh.readline.terminal.TerminalColorDetector;
import org.aesh.readline.terminal.formatting.TerminalColor;
import org.aesh.readline.terminal.formatting.TerminalString;
import org.aesh.terminal.utils.TerminalColorCapability;

public class AdaptiveRenderer implements OptionRenderer<ProcessedOption> {
    private final TerminalColorCapability capability;
    
    public AdaptiveRenderer(TerminalColorCapability capability) {
        this.capability = capability;
    }

    @Override
    public String render(ProcessedOption option) {
        // Use theme-aware colors that work on both light and dark backgrounds
        TerminalColor color = TerminalColor.forHighlight(capability);
        return new TerminalString(option.getValue(), color).toString();
    }
}

The semantic color methods automatically choose appropriate brightness:

MethodDark ThemeLight ThemeUse For
forError()Bright redNormal redError messages
forSuccess()Bright greenNormal greenSuccess confirmations
forWarning()Bright yellowNormal yellowWarnings
forInfo()Bright cyanNormal blueInformational text
forHighlight()Bright whiteBlackEmphasized text
forMuted()Normal whiteNormal blackSecondary text

See the Readline Terminal Colors documentation for more details on RGB colors and color depth adaptation.

Conditional Rendering

public class SmartPathRenderer implements OptionRenderer<ProcessedOption> {

    @Override
    public String render(ProcessedOption option) {
        String value = option.getValue();
        // Show relative paths, abbreviate long paths
        Path path = Paths.get(value);
        if (path.isAbsolute() && path.getNameCount() > 3) {
            return "..." + path.subpath(path.getNameCount() - 3, path.getNameCount());
        }
        return value;
    }
}

Default Value Display

Render default values in a specific format:

public class DefaultValueRenderer implements OptionRenderer<ProcessedOption> {

    @Override
    public String render(ProcessedOption option) {
        String value = option.getValue();
        String defaultValue = option.getDefaultValues().length > 0 
            ? option.getDefaultValues()[0] 
            : null;
        
        if (value != null && value.equals(defaultValue)) {
            return value + " (default)";
        }
        return value != null ? value : "not set";
    }
}