A Command option is defined by either an Option annotation or an OptionBuilder object. In this document we will focus on the annotations and its values. Æsh support several different options types each with defined as a seperate annotation. The differen annotations:

  • Option

    • The most common type with a specific name which can have one value (or none)

  • OptionList

    • The difference between Option and OptionList is that OptionList can have multiple values, by default the value separator is , (comma).

  • OptionGroup

    • OptionGroup is similar to OptionList, but it support specific name for each attribute. Eg: -DXm=100, where D is the option name, where Xm is given the value 100.

  • Arguments

    • Arguments is almost identical to OptionList except that it do not have a name. Arguments is required for commands that want argument options.

Common Option attributes

  • All the option types have a name and short name (except Arguments). Name is required, if no name is not provided Æsh will use the field name as the name. Æsh will be default add -- in front of each name on the command line, this is not possible to change. Short name is optional and if defined Æsh will add a - in front on the command line.

  • description and argument are both used for documentation and when Æsh generates info based on the metadata.

  • required specifies if this option is required to be set.

  • defaultValue will be displayed during completion (if it matches)

  • hasValue specifies if this option accept values. This option can only be set to true when the field type is boolean/Boolean. This attribute is only for the Option type.

  • overrideRequired will override missing required options. Very useful for help options etc.


All Option types have a Converter which is used to convert the input value (String) to the specific field object type. Æsh provides converters for:

  • Boolean/boolean

  • Byte/byte

  • Character/char

  • Double/double

  • File

  • Float/float

  • Integer/int

  • Long/long

  • Short/short

  • String

Any other object type need a specific converter. - and remember the converter must have a public constructor with no arguments.


A Completer is optional, but for better user experience we recommend that Completers are used. Æsh provide completers for:

  • File

  • Boolean

  • Default values

As Converters the Completer implementation must have a public constructor with no arguments.


OptionValidator is called just before Command.execute(…) and is used to ensure that the value given by the user is valid. OptionValidator is optional, but as with the attributes above we recommend that it is used.


Some options might depend on another option value to be set or a specific value before the option is "visible". By defining an OptionValidator you can define a specific logic that will trigger the visibility of the option. This attribute is highly optional.


With OptionRenderer you can specify how a specific option should look. Eg you can change the text color/background color and text type.

@CommandDefinition(name="ls", description = "[OPTION]... [FILE]...")
public static class TestCommand implements Command {

    @Option(shortName = 'f', hasValue = false, description = "set foo to true/false")
    private Boolean foo;

    @Option(hasValue = false, description = "set the bar", renderer = BlueBoldRenderer.class)
    private boolean bar;

    @Option(completer = TestCompleter.class, defaultValue = {"MORE"}, argument = "SIZE")
    private String less;

    @OptionList(defaultValue = "/tmp", description = "file location", valueSeparator = ':',
            validator = DirectoryValidator.class,
            activator = BarActivator.class)
    List<File> files;

    @Option(hasValue = false, description = "display this help and exit")
    private boolean help;

    private List<File> arguments;

    public CommandResult execute(CommandInvocation commandInvocation) throws IOException, InterruptedException {
        if(help) {
        else {
                commandInvocation.getShell().out().println("you set foo to: " + foo);
                commandInvocation.getShell().out().println("you set bar to: " + bar);
            if(less != null)
                commandInvocation.getShell().out().println("you set less to: " + less);
            if(files != null)
                commandInvocation.getShell().out().println("you set file to: " + files);

            if(arguments != null) {
                for(File f : arguments)
        return CommandResult.SUCCESS;

public static class TestCompleter implements OptionCompleter {

    public void complete(CompleterData completerData) {
        List<String> completeList = new ArrayList<String>();
        if(completerData.getGivenCompleteValue() == null ||
           completerData.getGivenCompleteValue().length() == 0)
        else {
            char lastChar =
            if(Character.isDigit(lastChar)) {
                int i = (int) lastChar;

public static class DirectoryValidator implements OptionValidator<File> {
    public void validate(File value) throws OptionValidatorException {
        if(!value.isDirectory()) {
            throw new OptionValidatorException("File validation failed, must be a directory.");

public static class BarActivator implements OptionActivator {

    public boolean isActivated(ProcessedCommand processedCommand) {
        ProcessedOption bar = processedCommand.findLongOption("bar");
        if(bar != null && bar.getValue() != null)
            return true;
            return false;

public static class BlueBoldRenderer implements OptionRenderer {

    private static TerminalTextStyle style = new TerminalTextStyle(CharacterType.UNDERLINE);
    private static TerminalColor color = new TerminalColor(42, Color.DEFAULT);

    public TerminalColor getColor() {
        return color;

    public TerminalTextStyle getTextType() {
        return style;
back to top