ArgHelp.java
package net.morimekta.terminal.args;
import net.morimekta.io.tty.TTY;
import net.morimekta.terminal.args.impl.ArgHelpImpl;
import java.io.PrintStream;
import java.util.Comparator;
import static java.util.Objects.requireNonNull;
/**
* Helper class to display help and usage for a program or sub-command.
*/
public interface ArgHelp {
/**
* @param parser The argument parser to build help helper for.
* @return The argument help builder.
*/
static Builder argHelp(ArgParser parser) {
return new ArgHelpImpl.BuilderImpl(parser);
}
/**
* Print the single line usage string to print stream. Contains a short-name
* flag list and a list of options and arguments. This will always be on a
* single line when called with this method.
* <p>
* Example single line usage: <code>[-sh] [--long] [--long L] [arg]</code>
*
* @param writer The print stream to write single line usage to.
*/
void printSingleLineUsage(PrintStream writer);
/**
* Print the preamble for the help with short options. Handy if you want to
* explain why some option was invalid, missing etc. Note that the single
* line usage will be formatted and wrapped to fit the usage width limit.
* <p>
* Example preamble with short overview of the program ant it's options:
* <pre>{@code
* {program description} - {version}
* Usage: {program} {single line usage}
* }</pre>
*
* @param writer The print stream to write preamble to.
*/
void printPreamble(PrintStream writer);
/**
* Print the help output for the argument parser, starting with base
* information about the program, the single line usage, and an overview
* over options, arguments and sub-commands. It will not print detailed
* options for sub-commands. To do that make an arg helper for the sub-
* -command parser, and print help for that. Note that the single line
* usage will be formatted and wrapped to fit the usage width limit.
* <p>
* Example help:
* <pre>{@code
* {program description} - {version}
* Usage: {program} {single line usage}
*
* {--longName} {metaVar} : {usage string} (default: {default})
* }</pre>
* <p>
* In order to print help for a sub-command do this:
* <pre>{@code
* argHelp(argParser.getSubCommandSet()
* .parserForSubCommand("name"))
* .printHelp(System.out);
* }</pre>
*
* @param writer The print stream to write help to.
* @see SubCommandSet#parserForSubCommand(String)
*/
void printHelp(PrintStream writer);
/**
* Builder for customizing printed help output.
*/
interface Builder {
/**
* @return The built helper.
*/
ArgHelp build();
/**
* @param prefix The prefix to show before the single line usage in the
* preamble. Defaults to <code>Usage: </code>. Should end
* with a space if present, otherwise there will be no
* space between the prefix and the program name.
* @return The builder.
*/
Builder singleLineUsagePrefix(String prefix);
/**
* @param comparator Comparator to sort options by when displaying help.
* Defaults to not sorted, so printed in order they
* were added to the {@link ArgParser.Builder}.
* @return The builder.
*/
Builder withOptionsComparator(Comparator<Option> comparator);
/**
* @param show If default values should be shown. Defaults to true.
* @return The builder.
*/
Builder showDefaults(boolean show);
/**
* @param show If hidden options should be shown. Defaults to false.
* @return The builder.
*/
Builder showHiddenOptions(boolean show);
/**
* @param show If hidden arguments should be shown. Defaults to false.
* @return The builder.
*/
Builder showHiddenArguments(boolean show);
/**
* @param show If hidden sub-commands should be shown. Defaults to false.
* @return The builder.
*/
Builder showHiddenSubCommands(boolean show);
/**
* @param show If sub-commands overview should be shown. Defaults to true.
* @return The builder.
*/
Builder showSubCommands(boolean show);
/**
* @param header Header string to show between option / argument overview
* and the sub-command overview.
* @return The builder.
*/
Builder subCommandsHeader(String header);
/**
* @param width Wrap usage description at this many characters width.
* @return The builder.
*/
Builder usageWidth(int width);
/**
* @param tty Set usage with from the terminal width of the TTY.
* @return The builder.
*/
default Builder usingTTYWidth(TTY tty) {
return usingTTYWidth(tty, Integer.MAX_VALUE);
}
/**
* Set usage with from the terminal width of the TTY but only up to
* a maximum.
*
* @param tty Set usage with from the terminal width of the TTY.
* @param maxWidth Max width of usage wrapping.
* @return The builder.
*/
default Builder usingTTYWidth(TTY tty, int maxWidth) {
requireNonNull(tty, "tty == null");
if (maxWidth < 1) {
throw new IllegalArgumentException("Invalid max width " + maxWidth);
}
return usageWidth(Math.min(tty.getTerminalSize().cols, maxWidth));
}
/**
* @param show If hidden options, arguments and sub-commands should be
* shown. Defaults to false.
* @return The builder.
*/
default Builder showHidden(boolean show) {
return showHiddenOptions(show)
.showHiddenArguments(show)
.showHiddenSubCommands(show);
}
/**
* Build and print the single line usage.
* See {@link ArgHelp#printSingleLineUsage(PrintStream)}
*
* @param writer The stream to write to.
*/
default void printSingleLineUsage(PrintStream writer) {
build().printSingleLineUsage(writer);
}
/**
* Build and print the help preamble.
* See {@link ArgHelp#printPreamble(PrintStream)}
*
* @param writer The stream to write to.
*/
default void printPreamble(PrintStream writer) {
build().printPreamble(writer);
}
/**
* Build and print help overview.
* See {@link ArgHelp#printHelp(PrintStream)}
*
* @param writer The stream to write to.
*/
default void printHelp(PrintStream writer) {
build().printHelp(writer);
}
}
}