Skip to content
Open
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ OPTIONS:

### 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.
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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes are removing links to the documentation (the double backticks) – can you revert that?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes!


Here's the same command with some extra customization:

Expand Down Expand Up @@ -76,7 +76,7 @@ OPTIONS:

### 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.
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 {
Expand All @@ -93,7 +93,7 @@ enum Fruit: String, ExpressibleByArgument {
struct FruitStore: ParsableCommand {
@Argument(help: "The fruit to purchase")
var fruit: Fruit

@Option(help: "The number of fruit to purchase")
var quantity: Int = 1
}
Expand All @@ -115,7 +115,7 @@ OPTIONS:

#### 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:
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 {
Expand All @@ -128,7 +128,7 @@ enum Fruit: String, CaseIterable, ExpressibleByArgument {
struct FruitStore: ParsableCommand {
@Argument(help: "The fruit to purchase")
var fruit: Fruit

@Option(help: "The number of fruit to purchase")
var quantity: Int = 1
}
Expand All @@ -148,7 +148,114 @@ OPTIONS:
-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.
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 Individual 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.

### Basic Enum Value Descriptions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use just one enum throughout this documentation, I think output format is a good example

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the other two sub-sections here will be eliminated, can you just use a single header for this section about customizing the value descriptions? This should use a level 4 header (i.e. ####) since it's under the "Enumerating Possible Values" section.


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 <format>]

OPTIONS:
--format <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.
```

### Array Options with Enum Descriptions
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this section needs to exist, since the customization / help screen display is the same whether a type is included a single option or as an array. The first sentence ("The same enum value descriptions...") could be included after the last example, if you'd like.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'll nuke this section.


The same enum value descriptions work seamlessly with array options, allowing users to understand each possible value when multiple selections are allowed:

```swift
struct DataExporter: ParsableCommand {
@Option(help: "Output formats to generate")
var formats: [OutputFormat] = [.json]
}
```

The help screen displays descriptions for each format option:

```
USAGE: data-exporter [--formats <formats> ...]

OPTIONS:
--formats <formats> Output formats to generate (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.
```

### Working with Raw Values

For enums with custom raw values, the descriptions work with the raw value representation. Here's the same `OutputFormat` enum with custom raw values:

```swift
enum OutputFormat: String, CaseIterable, ExpressibleByArgument {
case json = "json"
case yaml = "yml"
case xml = "xml"
case csv = "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
}
```

In this example, users would specify `--format yml` to get YAML output, but the help screen still shows the descriptive text.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The content in this section is covered above, under the "Deriving Possible Values" header. Could you look at improving that section if it doesn't cover what you'd like to see?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I think you're right, I was trying to cover all the cases and make this section be a no brainer read through. It can be removed.


### Controlling Argument Visibility

Expand All @@ -164,7 +271,7 @@ struct Example: ParsableCommand {
}
```

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.
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
Expand All @@ -181,7 +288,7 @@ OPTIONS:
-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.
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 {
Expand Down Expand Up @@ -220,7 +327,7 @@ OPTIONS:

### 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:
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 {
Expand Down