-
Notifications
You must be signed in to change notification settings - Fork 418
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow long options to be left-aligned in usage help #774
Comments
Note that this is already configurable and I will provide an example of how to accomplish this with the current version of picocli. |
The example below demonstrates how to left-align long options in the usage help. It currently is quite a bit of code. In future versions of picocli it would be nice to provide some API so that applications can accomplish this more easily. package picocli.examples.layout;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Help;
import picocli.CommandLine.Help.ColorScheme;
import picocli.CommandLine.IHelpFactory;
import picocli.CommandLine.Model.ArgSpec;
import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Option;
import java.util.concurrent.Callable;
@Command(name = "layout-demo", mixinStandardHelpOptions = true, description = "option list layout demo")
public class LayoutDemo implements Callable<Integer> {
@Option(names = "--large-option", description = "large option") boolean largeOption;
@Option(names = {"-l", "--long-option"}, description = "long option") String longOption;
@Override
public Integer call() {
// run the business logic
// ...
int exitCode = 0;
return exitCode;
}
public static void main(String[] args) {
CommandLine cmd = new CommandLine(new LayoutDemo());
// customize the usage help to left-align long options
cmd.setHelpFactory(createCustomizedUsageHelp());
// instead of cmd.execute, applications can also call cmd.parseArgs
System.exit(cmd.execute(args));
}
private static IHelpFactory createCustomizedUsageHelp() {
return new IHelpFactory() {
private static final int COLUMN_REQUIRED_OPTION_MARKER_WIDTH = 2;
private static final int COLUMN_SHORT_OPTION_NAME_WIDTH = 2;
private static final int COLUMN_OPTION_NAME_SEPARATOR_WIDTH = 2;
private static final int COLUMN_LONG_OPTION_NAME_WIDTH = 22;
private static final int INDEX_REQUIRED_OPTION_MARKER = 0;
private static final int INDEX_SHORT_OPTION_NAME = 1;
private static final int INDEX_OPTION_NAME_SEPARATOR = 2;
private static final int INDEX_LONG_OPTION_NAME = 3;
private static final int INDEX_OPTION_DESCRIPTION = 4;
@Override
public Help create(CommandSpec commandSpec, ColorScheme colorScheme) {
return new Help(commandSpec, colorScheme) {
@Override
public Layout createDefaultLayout() {
// The default layout creates a TextTable with 5 columns, as follows:
// 0: empty text or (if configured) the requiredOptionMarker character
// 1: short option name
// 2: comma separator (if option has both short and long option)
// 3: long option name(s)
// 4: option description
//
// The code below creates a TextTable with 3 columns, as follows:
// 0: empty text or (if configured) the requiredOptionMarker character
// 1: all option names, comma-separated if necessary
// 2: option description
int optionNamesColumnWidth = COLUMN_SHORT_OPTION_NAME_WIDTH +
COLUMN_OPTION_NAME_SEPARATOR_WIDTH +
COLUMN_LONG_OPTION_NAME_WIDTH;
TextTable table = TextTable.forColumnWidths(colorScheme.ansi(),
COLUMN_REQUIRED_OPTION_MARKER_WIDTH,
optionNamesColumnWidth,
commandSpec.usageMessage().width() - (optionNamesColumnWidth + COLUMN_REQUIRED_OPTION_MARKER_WIDTH));
Layout result = new Layout(colorScheme,
table,
createDefaultOptionRenderer(),
createDefaultParameterRenderer()) {
public void layout(ArgSpec argSpec, Ansi.Text[][] cellValues) {
// The default option renderer produces 5 Text values for each option.
// Below we combine the short option name, comma separator and long option name
// into a single Text object, and we pass 3 Text values to the TextTable.
for (Ansi.Text[] original : cellValues) {
if (original[INDEX_OPTION_NAME_SEPARATOR].getCJKAdjustedLength() > 0) {
original[INDEX_OPTION_NAME_SEPARATOR] = original[INDEX_OPTION_NAME_SEPARATOR].concat(" ");
}
Ansi.Text[] threeColumns = new Ansi.Text[] {
original[INDEX_REQUIRED_OPTION_MARKER],
original[INDEX_SHORT_OPTION_NAME]
.concat(original[INDEX_OPTION_NAME_SEPARATOR])
.concat(original[INDEX_LONG_OPTION_NAME]),
original[INDEX_OPTION_DESCRIPTION],
};
table.addRowValues(threeColumns);
}
}
};
return result;
}
};
}
};
}
} This produces the following usage help message. Note that the
|
Many commands do left-align long options, but an example of a command whose usage help shows the long options in a separate column is
Another is
|
The checkstyle team are not happy (see checkstyle/checkstyle#6924) with the option layout where short options are in a separate column from long options. They prefer a layout where long options appear left-aligned.
UPDATE (Aug 2019): the description of that ticket has been modified; all options in the checkstyle application now have a short name as well as a long name.
The text was updated successfully, but these errors were encountered: