# Customizing Help Support your users (and yourself) by providing rich help for arguments, options, and flags. ## Overview You can provide help text when declaring any `@Argument`, `@Option`, or `@Flag` by passing a string literal as the `help` parameter: ```swift struct Example: ParsableCommand { @Flag(help: "Display extra information while processing.") var verbose = false @Option(help: "The number of extra lines to show.") var extraLines = 0 @Argument(help: "The input file.") var inputFile: String? } ``` Users see these strings in the automatically-generated help screen, which is triggered by the `-h` or `--help` flags, by default: ``` % example --help USAGE: example [--verbose] [--extra-lines ] ARGUMENTS: The input file. OPTIONS: --verbose Display extra information while processing. --extra-lines The number of extra lines to show. (default: 0) -h, --help Show help information. ``` ### Customizing Help for Arguments For more control over the help text, pass an ``ArgumentHelp`` instance instead of a string literal. The `ArgumentHelp` type can include an abstract (which is what the string literal becomes), a discussion, a value name to use in the usage string, and a visibility level for that argument. Here's the same command with some extra customization: ```swift struct Example: ParsableCommand { @Flag(help: "Display extra information while processing.") var verbose = false @Option(help: ArgumentHelp( "The number of extra lines to show.", valueName: "n")) var extraLines = 0 @Argument(help: ArgumentHelp( "The input file.", discussion: "If no input file is provided, the tool reads from stdin.", valueName: "file")) var inputFile: String? } ``` ...and the help screen: ``` USAGE: example [--verbose] [--extra-lines ] [] ARGUMENTS: The input file. If no input file is provided, the tool reads from stdin. OPTIONS: --verbose Display extra information while processing. --extra-lines The number of extra lines to show. (default: 0) -h, --help Show help information. ``` ### Enumerating Possible Values When an argument or option has a fixed set of possible values, listing these values in the help screen can simplify use of your tool. You can customize the displayed set of values for custom ``ExpressibleByArgument`` types by implementing ``ExpressibleByArgument/allValueStrings``. Despite the name, ``ExpressibleByArgument/allValueStrings`` does _not_ need to be an exhaustive list of possible values. ```swift enum Fruit: String, ExpressibleByArgument { case apple case banana case coconut case dragonFruit = "dragon-fruit" static var allValueStrings: [String] { ["apple", "banana", "coconut", "dragon-fruit"] } } struct FruitStore: ParsableCommand { @Argument(help: "The fruit to purchase") var fruit: Fruit @Option(help: "The number of fruit to purchase") var quantity: Int = 1 } ``` The help screen includes the list of values in the description of the `` argument: ``` USAGE: fruit-store [--quantity ] ARGUMENTS: The fruit to purchase (values: apple, banana, coconut, dragon-fruit) OPTIONS: --quantity The number of fruit to purchase (default: 1) -h, --help Show help information. ``` #### Deriving Possible Values ExpressibleByArgument types that conform to `CaseIterable` do not need to manually specify ``ExpressibleByArgument/allValueStrings``. Instead, a list of possible values is derived from the type's cases, as in this updated example: ```swift enum Fruit: String, CaseIterable, ExpressibleByArgument { case apple case banana case coconut case dragonFruit = "dragon-fruit" } struct FruitStore: ParsableCommand { @Argument(help: "The fruit to purchase") var fruit: Fruit @Option(help: "The number of fruit to purchase") var quantity: Int = 1 } ``` The help screen still contains all the possible values. ``` USAGE: fruit-store [--quantity ] ARGUMENTS: The fruit to purchase (values: apple, banana, coconut, dragon-fruit) OPTIONS: --quantity The number of fruit to purchase (default: 1) -h, --help Show help information. ``` For an ``ExpressibleByArgument`` and `CaseIterable` type with many cases, you may still want to implement ``ExpressibleByArgument/allValueStrings`` to avoid an overly long list of values appearing in the help screen. For these types it is recommended to include the most common possible values. #### Providing Descriptions for Enum Values When your argument or option uses an enum type, you can provide detailed descriptions for each enum value that will appear in the help screen. This is especially useful when the enum cases represent complex concepts that benefit from explanation. To provide descriptions for individual enum values, implement a custom `defaultValueDescription` property for each case. The ArgumentParser will automatically detect when descriptions differ from the enum's string representation and display them in an enumerated format. ```swift enum OutputFormat: String, CaseIterable, ExpressibleByArgument { case json case yaml case xml case csv var defaultValueDescription: String { switch self { case .json: return "JavaScript Object Notation format" case .yaml: return "YAML Ain't Markup Language format" case .xml: return "eXtensible Markup Language format" case .csv: return "Comma-Separated Values format" } } } struct DataExporter: ParsableCommand { @Option(help: "Select output format") var format: OutputFormat = .json } ``` This produces help output with detailed descriptions for each enum value: ``` USAGE: data-exporter [--format ] OPTIONS: --format Select output format (default: json) json - JavaScript Object Notation format yaml - YAML Ain't Markup Language format xml - eXtensible Markup Language format csv - Comma-Separated Values format -h, --help Show help information. ``` ### Controlling Argument Visibility You can specify the visibility of any argument, option, or flag. ```swift struct Example: ParsableCommand { @Flag(help: ArgumentHelp("Show extra info.", visibility: .hidden)) var verbose: Bool = false @Flag(help: ArgumentHelp("Use the legacy format.", visibility: .private)) var useLegacyFormat: Bool = false } ``` The `--verbose` flag is only visible in the extended help screen. The `--use-legacy-format` stays hidden even in the extended help screen, due to its `.private` visibility. ``` % example --help USAGE: example OPTIONS: -h, --help Show help information. % example --help-hidden USAGE: example [--verbose] OPTIONS: --verbose Show extra info. -h, --help Show help information. ``` Alternatively, you can group multiple arguments, options, and flags together as part of a ``ParsableArguments`` type, and set the visibility when including them as an `@OptionGroup` property. ```swift struct ExperimentalFlags: ParsableArguments { @Flag(help: "Use the remote access token. (experimental)") var experimentalUseRemoteAccessToken: Bool = false @Flag(help: "Use advanced security. (experimental)") var experimentalAdvancedSecurity: Bool = false } struct Example: ParsableCommand { @OptionGroup(visibility: .hidden) var flags: ExperimentalFlags } ``` The members of `ExperimentalFlags` are only shown in the extended help screen: ``` % example --help USAGE: example OPTIONS: -h, --help Show help information. % example --help-hidden USAGE: example [--experimental-use-remote-access-token] [--experimental-advanced-security] OPTIONS: --experimental-use-remote-access-token Use the remote access token. (experimental) --experimental-advanced-security Use advanced security. (experimental) -h, --help Show help information. ``` ### Grouping Arguments in the Help Screen When you provide a title in an `@OptionGroup` declaration, that type's properties are grouped together under your title in the help screen. For example, this command bundles similar arguments together under a "Build Options" title: ```swift struct BuildOptions: ParsableArguments { @Option(help: "A setting to pass to the compiler.") var compilerSetting: [String] = [] @Option(help: "A setting to pass to the linker.") var linkerSetting: [String] = [] } struct Example: ParsableCommand { @Argument(help: "The input file to process.") var inputFile: String @Flag(help: "Show extra output.") var verbose: Bool = false @Option(help: "The path to a configuration file.") var configFile: String? @OptionGroup(title: "Build Options") var buildOptions: BuildOptions } ``` This grouping is reflected in the command's help screen: ``` % example --help USAGE: example [--verbose] [--config-file ] [--compiler-setting ...] [--linker-setting ...] ARGUMENTS: The input file to process. BUILD OPTIONS: --compiler-setting A setting to pass to the compiler. --linker-setting A setting to pass to the linker. OPTIONS: --verbose Show extra output. --config-file The path to a configuration file. -h, --help Show help information. ```