Skip to content
Option Lists

Option Lists

The @OptionList annotation defines options that accept multiple values separated by a delimiter.

Properties

PropertyTypeDefaultDescription
nameString""Option name (variable name if empty)
shortNamechar'\u0000'Short name (e.g., -p)
descriptionString""Help description
valueSeparatorchar','Character separating values (OptionList.NO_SEPARATOR disables splitting)
requiredbooleanfalseIs option required?
optionalValuebooleanfalseAllow the option bare (empty list); see below
fallbackValueString""Single value applied when the option is bare (implies optionalValue)
defaultValueString[]{}Default values
askIfNotSetbooleanfalsePrompt user if not set
converterClass<? extends Converter>NullConverter.classCustom value converter
completerClass<? extends OptionCompleter>NullOptionCompleter.classCustom completer
validatorClass<? extends OptionValidator>NullValidator.classCustom validator
activatorClass<? extends OptionActivator>NullActivator.classCustom activator
rendererClass<? extends OptionRenderer>NullOptionRenderer.classCustom renderer
parserClass<? extends OptionParser>AeshOptionParser.classCustom parser
aliasesString[]{}Alternative long names for this option
helpGroupString""Group heading for this option in help output (see Options - Help Grouping)
exclusiveWithString[]{}Names of mutually exclusive options (see Options - Mutually Exclusive Options)
visibilityOptionVisibilityBRIEFControls help and completion visibility (see Options - Visibility Levels)
orderintInteger.MAX_VALUEExplicit help-order position (see Options - Help Option Ordering)

Basic Example

@CommandDefinition(name = "build")
public class BuildCommand implements Command<CommandInvocation> {

    @OptionList(name = "modules", description = "Modules to build")
    private List<String> modules;

    @Override
    public CommandResult execute(CommandInvocation invocation) {
        invocation.println("Building: " + String.join(", ", modules));
        return CommandResult.SUCCESS;
    }
}

Usage: build --modules module1,module2,module3 Or with space: build --modules module1,module2,module3

Custom Separator

Use valueSeparator to change the delimiter:

@OptionList(name = "ports", valueSeparator = ':', description = "Port list")
private List<Integer> ports;

Usage: build --ports 8080:8081:8082

No Separator

When each occurrence of the option carries exactly one value that may itself contain the separator character (e.g., key=value pairs with commas), use OptionList.NO_SEPARATOR to disable splitting entirely:

@OptionList(name = "prop", valueSeparator = OptionList.NO_SEPARATOR, description = "Properties")
private List<String> props;
myapp --prop a=1,2 --prop b=3   # two values: "a=1,2" and "b=3"

Without NO_SEPARATOR, a=1,2 would split into two values. Completion appends a space (a new word) after a completed value rather than a separator.

Array Fields

@OptionList and @Arguments also accept array fields, converted element-wise like collections:

@OptionList(name = "dep", valueSeparator = OptionList.NO_SEPARATOR)
private String[] deps;

Multi-dimensional arrays are rejected at build time.

Optional Values on Lists

With optionalValue = true, the option may be given bare (arity 0..*). A bare occurrence sets the field to an empty list, which distinguishes “specified without values” (empty list) from “not specified at all” (null):

@OptionList(name = "find", optionalValue = true, description = "Files to find")
private List<String> find;
myapp run            # find == null (not specified)
myapp run --find     # find == [] (empty list)
myapp run --find a,b # find == [a, b]

fallbackValue implies optionalValue and applies a single value when the option is bare (but never when it is omitted):

@OptionList(name = "find", fallbackValue = "a", description = "Files to find")
private List<String> find;
myapp run            # find == null (not specified)
myapp run --find     # find == [a] (fallback)
myapp run --find a,b # find == [a, b] (explicit)

Value Attachment Syntaxes

@OptionList supports multiple ways to attach values, matching POSIX/GNU conventions:

# Space-separated (all shells)
-R -Xmx4G -R -Xms4G

# Equals-attached (short and long names)
-R=-Xmx4G
--runtime-option=-Xmx4G

# Bare-attached (short names only, since 3.16)
-R-Xmx4G -R-Xms4G

The bare-attached syntax (-R-Xmx4G) is common for JVM-style options where the value starts with a dash. This works for single-character short names without requiring = or a space:

@OptionList(shortName = 'R', name = "runtime-option")
private List<String> javaRuntimeOptions;
# All equivalent:
myapp -R-Xmx4G -R-Xms4G server.jar
myapp -R=-Xmx4G -R=-Xms4G server.jar
myapp -R -Xmx4G -R -Xms4G server.jar

When using a custom valueSeparator (e.g., comma), the separator is applied within the attached value:

# -o with valueSeparator=','
myapp -ofoo,bar,baz    # three values: foo, bar, baz
myapp -o=foo,bar       # two values: foo, bar

With Converter

@OptionList(
    name = "files", 
    converter = PathConverter.class,
    description = "List of files"
)
private List<Path> files;

public static class PathConverter implements Converter<Path> {
    @Override
    public Path convert(String input) {
        return Paths.get(input);
    }
}

Usage: process --files /path/file1.txt,/path/file2.txt

Default Values

@OptionList(
    defaultValue = {"core", "utils", "api"},
    description = "Modules"
)
private List<String> modules;

Set Collection

Use Set instead of List to eliminate duplicates:

@OptionList(description = "Unique tags")
private Set<String> tags;

Aliases

Provide alternative long names with aliases:

@OptionList(name = "items", aliases = {"item"}, description = "Items to process")
private List<String> items;

Both --items a,b,c and --item a,b,c are accepted. See Options - Option Aliases for more details.

Custom Types

@OptionList(converter = VersionConverter.class, description = "Supported versions")
private List<Version> versions;