From f0c353a5b879265cf380cf49eef067cc830ede6f Mon Sep 17 00:00:00 2001 From: Raj Date: Wed, 29 Apr 2026 20:15:49 -0700 Subject: [PATCH 1/5] Add extendedDiscussion to CommandConfiguration --- .../Parsable Types/CommandConfiguration.swift | 14 ++ .../Usage/DumpHelpGenerator.swift | 1 + .../ArgumentParser/Usage/HelpGenerator.swift | 15 +- Sources/ArgumentParserToolInfo/ToolInfo.swift | 7 + .../DumpHelpGenerationTests.swift | 14 ++ .../HelpGenerationTests.swift | 167 ++++++++++++++++++ .../testExtendedDiscussionDumpHelp().json | 100 +++++++++++ .../Extensions/ArgumentParser+Markdown.swift | 4 + .../DSL/MultiPageDescription.swift | 5 + .../DSL/SinglePageDescription.swift | 5 + 10 files changed, 331 insertions(+), 1 deletion(-) create mode 100644 Tests/ArgumentParserUnitTests/Snapshots/testExtendedDiscussionDumpHelp().json diff --git a/Sources/ArgumentParser/Parsable Types/CommandConfiguration.swift b/Sources/ArgumentParser/Parsable Types/CommandConfiguration.swift index ae5f85a70..eda8f4eeb 100644 --- a/Sources/ArgumentParser/Parsable Types/CommandConfiguration.swift +++ b/Sources/ArgumentParser/Parsable Types/CommandConfiguration.swift @@ -43,6 +43,14 @@ public struct CommandConfiguration: Sendable { /// a static block of text that extends the description of the argument. public var discussion: String + /// Additional information to be shown at the end of the help display, + /// after the list of arguments, options, and subcommands. + /// + /// Use `extendedDiscussion` for information that supplements the quick + /// reference provided by the argument list, such as usage examples, + /// additional details, or notes about the command's behavior. + public var extendedDiscussion: String + /// Version information for this command. public var version: String @@ -97,6 +105,8 @@ public struct CommandConfiguration: Sendable { /// automatically generating a usage description. Passing an empty string /// hides the usage string altogether. /// - discussion: A longer description of the command. + /// - extendedDiscussion: Additional information shown at the end of the + /// help display, after the argument, option, and subcommand lists. /// - version: The version number for this command. When you provide a /// non-empty string, the argument parser prints it if the user provides /// a `--version` flag. @@ -120,6 +130,7 @@ public struct CommandConfiguration: Sendable { abstract: String = "", usage: String? = nil, discussion: String = "", + extendedDiscussion: String = "", version: String = "", shouldDisplay: Bool = true, subcommands ungroupedSubcommands: [ParsableCommand.Type] = [], @@ -132,6 +143,7 @@ public struct CommandConfiguration: Sendable { self.abstract = abstract self.usage = usage self.discussion = discussion + self.extendedDiscussion = extendedDiscussion self.version = version self.shouldDisplay = shouldDisplay self.ungroupedSubcommands = ungroupedSubcommands @@ -149,6 +161,7 @@ public struct CommandConfiguration: Sendable { abstract: String = "", usage: String? = nil, discussion: String = "", + extendedDiscussion: String = "", version: String = "", shouldDisplay: Bool = true, subcommands ungroupedSubcommands: [ParsableCommand.Type] = [], @@ -162,6 +175,7 @@ public struct CommandConfiguration: Sendable { self.abstract = abstract self.usage = usage self.discussion = discussion + self.extendedDiscussion = extendedDiscussion self.version = version self.shouldDisplay = shouldDisplay self.ungroupedSubcommands = ungroupedSubcommands diff --git a/Sources/ArgumentParser/Usage/DumpHelpGenerator.swift b/Sources/ArgumentParser/Usage/DumpHelpGenerator.swift index 002d564f5..3ea7b5127 100644 --- a/Sources/ArgumentParser/Usage/DumpHelpGenerator.swift +++ b/Sources/ArgumentParser/Usage/DumpHelpGenerator.swift @@ -86,6 +86,7 @@ extension CommandInfoV0 { aliases: command.configuration.aliases, abstract: command.configuration.abstract, discussion: command.configuration.discussion, + extendedDiscussion: command.configuration.extendedDiscussion, defaultSubcommand: defaultSubcommand, subcommands: subcommands, arguments: arguments) diff --git a/Sources/ArgumentParser/Usage/HelpGenerator.swift b/Sources/ArgumentParser/Usage/HelpGenerator.swift index 1b46b73d5..2805fd4df 100644 --- a/Sources/ArgumentParser/Usage/HelpGenerator.swift +++ b/Sources/ArgumentParser/Usage/HelpGenerator.swift @@ -152,6 +152,7 @@ internal struct HelpGenerator { var abstract: String var usage: String var sections: [Section] + var extendedDiscussion: String init(commandStack: [ParsableCommand.Type], visibility: ArgumentVisibility) { guard let root = commandStack.first, let currentCommand = commandStack.last @@ -191,6 +192,7 @@ internal struct HelpGenerator { self.sections = HelpGenerator.generateSections( commandStack: commandStack, visibility: visibility) + self.extendedDiscussion = currentCommand.configuration.extendedDiscussion } init(_ type: ParsableArguments.Type, visibility: ArgumentVisibility) { @@ -408,6 +410,17 @@ internal struct HelpGenerator { """ } + let renderedExtendedDiscussion: String + if extendedDiscussion.isEmpty { + renderedExtendedDiscussion = "" + } else if helpSubcommandMessage.isEmpty { + renderedExtendedDiscussion = + "\n" + extendedDiscussion.wrapped(to: screenWidth) + } else { + renderedExtendedDiscussion = + "\n\n" + extendedDiscussion.wrapped(to: screenWidth) + } + let renderedUsage = usage.isEmpty ? "" @@ -416,7 +429,7 @@ internal struct HelpGenerator { return """ \(renderedAbstract)\ \(renderedUsage)\ - \(renderedSections)\(helpSubcommandMessage) + \(renderedSections)\(helpSubcommandMessage)\(renderedExtendedDiscussion) """ } } diff --git a/Sources/ArgumentParserToolInfo/ToolInfo.swift b/Sources/ArgumentParserToolInfo/ToolInfo.swift index 825799781..dfa6fab87 100644 --- a/Sources/ArgumentParserToolInfo/ToolInfo.swift +++ b/Sources/ArgumentParserToolInfo/ToolInfo.swift @@ -56,6 +56,9 @@ public struct CommandInfoV0: Codable, Hashable { /// Extended description of the command's functionality. public var discussion: String? + /// Additional information shown at the end of help, after the argument list. + public var extendedDiscussion: String? + /// Optional name of the subcommand invoked when the command is invoked with /// no arguments. public var defaultSubcommand: String? @@ -71,6 +74,7 @@ public struct CommandInfoV0: Codable, Hashable { aliases: [String]?, abstract: String, discussion: String, + extendedDiscussion: String, defaultSubcommand: String?, subcommands: [CommandInfoV0], arguments: [ArgumentInfoV0] @@ -82,6 +86,7 @@ public struct CommandInfoV0: Codable, Hashable { self.aliases = aliases?.nonEmpty self.abstract = abstract.nonEmpty self.discussion = discussion.nonEmpty + self.extendedDiscussion = extendedDiscussion.nonEmpty self.defaultSubcommand = defaultSubcommand?.nonEmpty self.subcommands = subcommands.nonEmpty @@ -99,6 +104,8 @@ public struct CommandInfoV0: Codable, Hashable { String.self, forKey: .abstract) self.discussion = try container.decodeIfPresent( String.self, forKey: .discussion) + self.extendedDiscussion = try container.decodeIfPresent( + String.self, forKey: .extendedDiscussion) self.shouldDisplay = try container.decodeIfPresent(Bool.self, forKey: .shouldDisplay) ?? true self.defaultSubcommand = try container.decodeIfPresent( diff --git a/Tests/ArgumentParserUnitTests/DumpHelpGenerationTests.swift b/Tests/ArgumentParserUnitTests/DumpHelpGenerationTests.swift index 9a652479c..db3d49803 100644 --- a/Tests/ArgumentParserUnitTests/DumpHelpGenerationTests.swift +++ b/Tests/ArgumentParserUnitTests/DumpHelpGenerationTests.swift @@ -42,6 +42,10 @@ final class DumpHelpGenerationTests: XCTestCase { func testMathStatsDumpHelp() throws { try assertDumpHelp(command: "math stats") } + + func testExtendedDiscussionDumpHelp() throws { + try assertDumpHelp(type: ExtendedDiscussionCommand.self) + } } extension DumpHelpGenerationTests { @@ -128,4 +132,14 @@ extension DumpHelpGenerationTests { @Option(help: .init(discussion: "A discussion.")) var discussion: String } + + struct ExtendedDiscussionCommand: ParsableCommand { + static let configuration = CommandConfiguration( + abstract: "A command with extended discussion.", + discussion: "Top-level discussion.", + extendedDiscussion: "Additional info after the options.") + + @Option(help: "A name.") + var name: String + } } diff --git a/Tests/ArgumentParserUnitTests/HelpGenerationTests.swift b/Tests/ArgumentParserUnitTests/HelpGenerationTests.swift index f83390986..919c89356 100644 --- a/Tests/ArgumentParserUnitTests/HelpGenerationTests.swift +++ b/Tests/ArgumentParserUnitTests/HelpGenerationTests.swift @@ -1533,4 +1533,171 @@ extension HelpGenerationTests { """) } + + // MARK: - Extended Discussion + + struct ExtDiscussion: ParsableCommand { + static let configuration = CommandConfiguration( + abstract: "A test command.", + discussion: "Some discussion.", + extendedDiscussion: "This is extended info shown after the options.") + + @Option(help: "A name.") + var name: String + } + + func testHelpWithExtendedDiscussion() { + AssertHelp( + .default, for: ExtDiscussion.self, + equals: """ + OVERVIEW: A test command. + + Some discussion. + + USAGE: ext-discussion --name + + OPTIONS: + --name A name. + -h, --help Show help information. + + This is extended info shown after the options. + """) + } + + struct ExtDiscussionOnly: ParsableCommand { + static let configuration = CommandConfiguration( + extendedDiscussion: "Only extended text, no abstract or discussion.") + + @Flag(help: "Verbose output.") + var verbose = false + } + + func testHelpWithExtendedDiscussionOnly() { + AssertHelp( + .default, for: ExtDiscussionOnly.self, + equals: """ + USAGE: ext-discussion-only [--verbose] + + OPTIONS: + --verbose Verbose output. + -h, --help Show help information. + + Only extended text, no abstract or discussion. + """) + } + + struct ExtDiscussionWithSubcommands: ParsableCommand { + static let configuration = CommandConfiguration( + abstract: "A root command.", + extendedDiscussion: "Extended notes after subcommands.", + subcommands: [Sub.self]) + + struct Sub: ParsableCommand { + static let configuration = CommandConfiguration( + abstract: "A subcommand.", + extendedDiscussion: "Sub-level extended discussion.") + } + } + + func testHelpWithExtendedDiscussionAndSubcommands() { + AssertHelp( + .default, for: ExtDiscussionWithSubcommands.self, + equals: """ + OVERVIEW: A root command. + + USAGE: ext-discussion-with-subcommands + + OPTIONS: + -h, --help Show help information. + + SUBCOMMANDS: + sub A subcommand. + + See 'ext-discussion-with-subcommands help ' for detailed help. + + Extended notes after subcommands. + """) + } + + func testHelpWithExtendedDiscussionOnSubcommand() { + AssertHelp( + .default, for: ExtDiscussionWithSubcommands.Sub.self, + root: ExtDiscussionWithSubcommands.self, + equals: """ + OVERVIEW: A subcommand. + + USAGE: ext-discussion-with-subcommands sub + + OPTIONS: + -h, --help Show help information. + + Sub-level extended discussion. + """) + } + + func testHelpWithExtendedDiscussionHidden() { + AssertHelp( + .hidden, for: ExtDiscussion.self, + equals: """ + OVERVIEW: A test command. + + Some discussion. + + USAGE: ext-discussion --name + + OPTIONS: + --name A name. + -h, --help Show help information. + + This is extended info shown after the options. + """) + } + + struct ExtDiscussionWrapping: ParsableCommand { + static let configuration = CommandConfiguration( + extendedDiscussion: """ + This is a long extended discussion that should wrap when rendered \ + at eighty columns because it exceeds the screen width significantly. + """) + } + + func testHelpWithExtendedDiscussionWrapping() { + AssertHelp( + .default, for: ExtDiscussionWrapping.self, + columns: 80, + equals: """ + USAGE: ext-discussion-wrapping + + OPTIONS: + -h, --help Show help information. + + This is a long extended discussion that should wrap when rendered at eighty + columns because it exceeds the screen width significantly. + """) + } + + struct ExtDiscussionMultiParagraph: ParsableCommand { + static let configuration = CommandConfiguration( + extendedDiscussion: """ + First paragraph with details. + + Second paragraph with more info. + """) + } + + func testHelpWithExtendedDiscussionMultiParagraph() { + AssertHelp( + .default, for: ExtDiscussionMultiParagraph.self, + columns: 80, + equals: """ + USAGE: ext-discussion-multi-paragraph + + OPTIONS: + -h, --help Show help information. + + First paragraph with details. + + Second paragraph with more info. + """) + } } diff --git a/Tests/ArgumentParserUnitTests/Snapshots/testExtendedDiscussionDumpHelp().json b/Tests/ArgumentParserUnitTests/Snapshots/testExtendedDiscussionDumpHelp().json new file mode 100644 index 000000000..b34318b08 --- /dev/null +++ b/Tests/ArgumentParserUnitTests/Snapshots/testExtendedDiscussionDumpHelp().json @@ -0,0 +1,100 @@ +{ + "command" : { + "abstract" : "A command with extended discussion.", + "arguments" : [ + { + "abstract" : "A name.", + "isOptional" : false, + "isRepeating" : false, + "kind" : "option", + "names" : [ + { + "kind" : "long", + "name" : "name" + } + ], + "parsingStrategy" : "default", + "preferredName" : { + "kind" : "long", + "name" : "name" + }, + "shouldDisplay" : true, + "valueName" : "name" + }, + { + "abstract" : "Show help information.", + "isOptional" : true, + "isRepeating" : false, + "kind" : "flag", + "names" : [ + { + "kind" : "short", + "name" : "h" + }, + { + "kind" : "long", + "name" : "help" + } + ], + "parsingStrategy" : "default", + "preferredName" : { + "kind" : "long", + "name" : "help" + }, + "shouldDisplay" : true, + "valueName" : "help" + } + ], + "commandName" : "extended-discussion-command", + "discussion" : "Top-level discussion.", + "extendedDiscussion" : "Additional info after the options.", + "shouldDisplay" : true, + "subcommands" : [ + { + "abstract" : "Show subcommand help information.", + "arguments" : [ + { + "isOptional" : true, + "isRepeating" : true, + "kind" : "positional", + "parsingStrategy" : "default", + "shouldDisplay" : true, + "valueName" : "subcommands" + }, + { + "isOptional" : true, + "isRepeating" : false, + "kind" : "flag", + "names" : [ + { + "kind" : "short", + "name" : "h" + }, + { + "kind" : "long", + "name" : "help" + }, + { + "kind" : "longWithSingleDash", + "name" : "help" + } + ], + "parsingStrategy" : "default", + "preferredName" : { + "kind" : "long", + "name" : "help" + }, + "shouldDisplay" : false, + "valueName" : "help" + } + ], + "commandName" : "help", + "shouldDisplay" : true, + "superCommands" : [ + "extended-discussion-command" + ] + } + ] + }, + "serializationVersion" : 0 +} \ No newline at end of file diff --git a/Tools/generate-docc-reference/Extensions/ArgumentParser+Markdown.swift b/Tools/generate-docc-reference/Extensions/ArgumentParser+Markdown.swift index 722245fed..7d44e69e1 100644 --- a/Tools/generate-docc-reference/Extensions/ArgumentParser+Markdown.swift +++ b/Tools/generate-docc-reference/Extensions/ArgumentParser+Markdown.swift @@ -100,6 +100,10 @@ extension CommandInfoV0 { } } + if let extendedDiscussion = self.extendedDiscussion { + result += "\(extendedDiscussion)\n\n" + } + for subcommand in self.subcommands ?? [] { result += subcommand.toMarkdown( diff --git a/Tools/generate-manual/DSL/MultiPageDescription.swift b/Tools/generate-manual/DSL/MultiPageDescription.swift index 4927e5b57..e0ff48883 100644 --- a/Tools/generate-manual/DSL/MultiPageDescription.swift +++ b/Tools/generate-manual/DSL/MultiPageDescription.swift @@ -50,6 +50,11 @@ struct MultiPageDescription: MDocComponent { } } } + + if let extendedDiscussion = command.extendedDiscussion { + MDocMacro.ParagraphBreak() + extendedDiscussion + } } } } diff --git a/Tools/generate-manual/DSL/SinglePageDescription.swift b/Tools/generate-manual/DSL/SinglePageDescription.swift index 1c30d3f9e..5af2d0745 100644 --- a/Tools/generate-manual/DSL/SinglePageDescription.swift +++ b/Tools/generate-manual/DSL/SinglePageDescription.swift @@ -72,5 +72,10 @@ struct SinglePageDescription: MDocComponent { SinglePageDescription(command: subcommand, root: false).core } } + + if let extendedDiscussion = command.extendedDiscussion { + MDocMacro.ParagraphBreak() + extendedDiscussion + } } } From e7c5f55a376673bd51c0d12c6aac21cf7af4bba9 Mon Sep 17 00:00:00 2001 From: Raj Date: Wed, 29 Apr 2026 20:36:11 -0700 Subject: [PATCH 2/5] Add docs --- .../Articles/CustomizingCommandHelp.md | 35 +++++++++++++++++++ .../Extensions/CommandConfiguration.md | 3 +- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/Sources/ArgumentParser/Documentation.docc/Articles/CustomizingCommandHelp.md b/Sources/ArgumentParser/Documentation.docc/Articles/CustomizingCommandHelp.md index c7eaf1eac..23c2bcb4e 100644 --- a/Sources/ArgumentParser/Documentation.docc/Articles/CustomizingCommandHelp.md +++ b/Sources/ArgumentParser/Documentation.docc/Articles/CustomizingCommandHelp.md @@ -59,6 +59,41 @@ hello! ... ``` +### Adding Extended Discussion + +Use the `extendedDiscussion` parameter to provide additional information that +appears at the end of the help screen, after the list of arguments, options, +and subcommands. This keeps the quick-reference argument list near the top of +the help output. + +```swift +struct Repeat: ParsableCommand { + static let configuration = CommandConfiguration( + abstract: "Repeats your input phrase.", + extendedDiscussion: """ + Use CTRL-C to stop repeating when no count is given. + """) + + // ... +} +``` + +``` +% repeat --help +OVERVIEW: Repeats your input phrase. + +USAGE: repeat [--count ] + +ARGUMENTS: + The phrase to repeat. + +OPTIONS: + --count How many times to repeat. + -h, --help Show help information. + +Use CTRL-C to stop repeating when no count is given. +``` + ### Modifying the Help Flag Names Users can see the help screen for a command by passing either the `-h` or the `--help` flag, by default. If you need to use one of those flags for another purpose, you can provide alternative names when configuring a root command. diff --git a/Sources/ArgumentParser/Documentation.docc/Extensions/CommandConfiguration.md b/Sources/ArgumentParser/Documentation.docc/Extensions/CommandConfiguration.md index 922707562..fbb7be762 100644 --- a/Sources/ArgumentParser/Documentation.docc/Extensions/CommandConfiguration.md +++ b/Sources/ArgumentParser/Documentation.docc/Extensions/CommandConfiguration.md @@ -4,12 +4,13 @@ ### Creating a Configuration -- ``init(commandName:abstract:usage:discussion:version:shouldDisplay:subcommands:groupedSubcommands:defaultSubcommand:helpNames:aliases:)`` +- ``init(commandName:abstract:usage:discussion:extendedDiscussion:version:shouldDisplay:subcommands:groupedSubcommands:defaultSubcommand:helpNames:aliases:)`` ### Customizing the Help Screen - ``abstract`` - ``discussion`` +- ``extendedDiscussion`` - ``usage`` - ``helpNames`` From 5c5e4c254201af8b84596ab5e079b15445eb3089 Mon Sep 17 00:00:00 2001 From: Raj Date: Wed, 29 Apr 2026 22:01:08 -0700 Subject: [PATCH 3/5] Preserve deprecated overloads for prior CommandConfiguration initializers --- .../Parsable Types/CommandConfiguration.swift | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/Sources/ArgumentParser/Parsable Types/CommandConfiguration.swift b/Sources/ArgumentParser/Parsable Types/CommandConfiguration.swift index eda8f4eeb..66115bc12 100644 --- a/Sources/ArgumentParser/Parsable Types/CommandConfiguration.swift +++ b/Sources/ArgumentParser/Parsable Types/CommandConfiguration.swift @@ -187,6 +187,74 @@ public struct CommandConfiguration: Sendable { } extension CommandConfiguration { + @available( + *, deprecated, + message: + "Use the memberwise initializer with the extendedDiscussion parameter." + ) + public init( + commandName: String? = nil, + abstract: String = "", + usage: String? = nil, + discussion: String = "", + version: String = "", + shouldDisplay: Bool = true, + subcommands: [ParsableCommand.Type] = [], + groupedSubcommands: [CommandGroup] = [], + defaultSubcommand: ParsableCommand.Type? = nil, + helpNames: NameSpecification? = nil, + aliases: [String] = [] + ) { + self.init( + commandName: commandName, + abstract: abstract, + usage: usage, + discussion: discussion, + extendedDiscussion: "", + version: version, + shouldDisplay: shouldDisplay, + subcommands: subcommands, + groupedSubcommands: groupedSubcommands, + defaultSubcommand: defaultSubcommand, + helpNames: helpNames, + aliases: aliases) + } + + @available( + *, deprecated, + message: + "Use the memberwise initializer with the extendedDiscussion parameter." + ) + public init( + commandName: String? = nil, + _superCommandName: String, + abstract: String = "", + usage: String? = nil, + discussion: String = "", + version: String = "", + shouldDisplay: Bool = true, + subcommands: [ParsableCommand.Type] = [], + groupedSubcommands: [CommandGroup] = [], + defaultSubcommand: ParsableCommand.Type? = nil, + helpNames: NameSpecification? = nil, + aliases: [String] = [] + ) { + self.init( + commandName: commandName, + _superCommandName: _superCommandName, + abstract: abstract, + usage: usage, + discussion: discussion, + extendedDiscussion: "", + version: version, + shouldDisplay: shouldDisplay, + subcommands: subcommands, + groupedSubcommands: groupedSubcommands, + defaultSubcommand: defaultSubcommand, + helpNames: helpNames, + aliases: aliases) + } + @available( *, deprecated, message: "Use the memberwise initializer with the aliases parameter." @@ -207,6 +275,7 @@ extension CommandConfiguration { abstract: abstract, usage: usage, discussion: discussion, + extendedDiscussion: "", version: version, shouldDisplay: shouldDisplay, subcommands: subcommands, @@ -235,6 +304,7 @@ extension CommandConfiguration { abstract: abstract, usage: "", discussion: discussion, + extendedDiscussion: "", version: version, shouldDisplay: shouldDisplay, subcommands: subcommands, From a0b879f0e8765838e16eeb92ada02a2f2cae5f2d Mon Sep 17 00:00:00 2001 From: Raj Date: Thu, 30 Apr 2026 12:19:38 -0700 Subject: [PATCH 4/5] Add extendedDiscussion example --- Examples/math/Math.swift | 9 +++++++++ Tests/ArgumentParserExampleTests/MathExampleTests.swift | 5 +++++ .../Snapshots/testMathDoccReference().md | 5 +++++ .../Snapshots/testMathMarkdownReference().md | 5 +++++ .../Snapshots/testMathMultiPageManual().mdoc | 5 +++++ .../Snapshots/testMathSinglePageManual().mdoc | 5 +++++ .../Snapshots/testMathDumpHelp().json | 1 + 7 files changed, 35 insertions(+) diff --git a/Examples/math/Math.swift b/Examples/math/Math.swift index 056c222d7..cd80bc2de 100644 --- a/Examples/math/Math.swift +++ b/Examples/math/Math.swift @@ -19,6 +19,15 @@ struct Math: ParsableCommand { // Optional abstracts and discussions are used for help output. abstract: "A utility for performing maths.", + // Extended discussion appears at the bottom of the help screen, + // after the list of subcommands. + extendedDiscussion: """ + Examples: + math add 10 15 20 + math multiply --hex-output 16 32 + math stats average --kind median 5 8 12 + """, + // Commands can define a version for automatic '--version' support. version: "1.0.0", diff --git a/Tests/ArgumentParserExampleTests/MathExampleTests.swift b/Tests/ArgumentParserExampleTests/MathExampleTests.swift index 64f1ac0e0..f5289cde3 100644 --- a/Tests/ArgumentParserExampleTests/MathExampleTests.swift +++ b/Tests/ArgumentParserExampleTests/MathExampleTests.swift @@ -42,6 +42,11 @@ final class MathExampleTests: XCTestCase { See 'math help ' for detailed help. + Examples: + math add 10 15 20 + math multiply --hex-output 16 32 + math stats average --kind median 5 8 12 + """ try AssertExecuteCommand(command: "math -h", expected: helpText) diff --git a/Tests/ArgumentParserGenerateDoccReferenceTests/Snapshots/testMathDoccReference().md b/Tests/ArgumentParserGenerateDoccReferenceTests/Snapshots/testMathDoccReference().md index 847a76462..844bb96c1 100644 --- a/Tests/ArgumentParserGenerateDoccReferenceTests/Snapshots/testMathDoccReference().md +++ b/Tests/ArgumentParserGenerateDoccReferenceTests/Snapshots/testMathDoccReference().md @@ -18,6 +18,11 @@ math [--version] [--help] *Show help information.* +Examples: + math add 10 15 20 + math multiply --hex-output 16 32 + math stats average --kind median 5 8 12 + ## math.add Print the sum of the values. diff --git a/Tests/ArgumentParserGenerateDoccReferenceTests/Snapshots/testMathMarkdownReference().md b/Tests/ArgumentParserGenerateDoccReferenceTests/Snapshots/testMathMarkdownReference().md index 00997feb5..e620562c2 100644 --- a/Tests/ArgumentParserGenerateDoccReferenceTests/Snapshots/testMathMarkdownReference().md +++ b/Tests/ArgumentParserGenerateDoccReferenceTests/Snapshots/testMathMarkdownReference().md @@ -18,6 +18,11 @@ math [--version] [--help] *Show help information.* +Examples: + math add 10 15 20 + math multiply --hex-output 16 32 + math stats average --kind median 5 8 12 + ## math.add Print the sum of the values. diff --git a/Tests/ArgumentParserGenerateManualTests/Snapshots/testMathMultiPageManual().mdoc b/Tests/ArgumentParserGenerateManualTests/Snapshots/testMathMultiPageManual().mdoc index 9ea160e4e..8a9eb6fd0 100644 --- a/Tests/ArgumentParserGenerateManualTests/Snapshots/testMathMultiPageManual().mdoc +++ b/Tests/ArgumentParserGenerateManualTests/Snapshots/testMathMultiPageManual().mdoc @@ -17,6 +17,11 @@ Show the version. .It Fl h , -help Show help information. .El +.Pp +Examples: + math add 10 15 20 + math multiply --hex-output 16 32 + math stats average --kind median 5 8 12 .Sh "SEE ALSO" .Xr math.add 9 , .Xr math.help 9 , diff --git a/Tests/ArgumentParserGenerateManualTests/Snapshots/testMathSinglePageManual().mdoc b/Tests/ArgumentParserGenerateManualTests/Snapshots/testMathSinglePageManual().mdoc index 8a5c64de7..15523e215 100644 --- a/Tests/ArgumentParserGenerateManualTests/Snapshots/testMathSinglePageManual().mdoc +++ b/Tests/ArgumentParserGenerateManualTests/Snapshots/testMathSinglePageManual().mdoc @@ -97,6 +97,11 @@ Show subcommand help information. Show the version. .El .El +.Pp +Examples: + math add 10 15 20 + math multiply --hex-output 16 32 + math stats average --kind median 5 8 12 .Sh AUTHORS The .Nm diff --git a/Tests/ArgumentParserUnitTests/Snapshots/testMathDumpHelp().json b/Tests/ArgumentParserUnitTests/Snapshots/testMathDumpHelp().json index cca3abc42..e1dec069c 100644 --- a/Tests/ArgumentParserUnitTests/Snapshots/testMathDumpHelp().json +++ b/Tests/ArgumentParserUnitTests/Snapshots/testMathDumpHelp().json @@ -46,6 +46,7 @@ } ], "commandName" : "math", + "extendedDiscussion" : "Examples:\n math add 10 15 20\n math multiply --hex-output 16 32\n math stats average --kind median 5 8 12", "shouldDisplay" : true, "subcommands" : [ { From d92cdff4abe7bd785eb6842def025da28656408c Mon Sep 17 00:00:00 2001 From: Raj Date: Thu, 30 Apr 2026 16:59:26 -0700 Subject: [PATCH 5/5] Move extendedDiscussion after subcommands in DocC reference output --- .../Snapshots/testMathDoccReference().md | 10 +++++----- .../Snapshots/testMathMarkdownReference().md | 10 +++++----- .../Extensions/ArgumentParser+Markdown.swift | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Tests/ArgumentParserGenerateDoccReferenceTests/Snapshots/testMathDoccReference().md b/Tests/ArgumentParserGenerateDoccReferenceTests/Snapshots/testMathDoccReference().md index 844bb96c1..5e30023dc 100644 --- a/Tests/ArgumentParserGenerateDoccReferenceTests/Snapshots/testMathDoccReference().md +++ b/Tests/ArgumentParserGenerateDoccReferenceTests/Snapshots/testMathDoccReference().md @@ -18,11 +18,6 @@ math [--version] [--help] *Show help information.* -Examples: - math add 10 15 20 - math multiply --hex-output 16 32 - math stats average --kind median 5 8 12 - ## math.add Print the sum of the values. @@ -232,4 +227,9 @@ math help [...] [--version] +Examples: + math add 10 15 20 + math multiply --hex-output 16 32 + math stats average --kind median 5 8 12 + diff --git a/Tests/ArgumentParserGenerateDoccReferenceTests/Snapshots/testMathMarkdownReference().md b/Tests/ArgumentParserGenerateDoccReferenceTests/Snapshots/testMathMarkdownReference().md index e620562c2..c538469b5 100644 --- a/Tests/ArgumentParserGenerateDoccReferenceTests/Snapshots/testMathMarkdownReference().md +++ b/Tests/ArgumentParserGenerateDoccReferenceTests/Snapshots/testMathMarkdownReference().md @@ -18,11 +18,6 @@ math [--version] [--help] *Show help information.* -Examples: - math add 10 15 20 - math multiply --hex-output 16 32 - math stats average --kind median 5 8 12 - ## math.add Print the sum of the values. @@ -228,4 +223,9 @@ math help [...] [--version] +Examples: + math add 10 15 20 + math multiply --hex-output 16 32 + math stats average --kind median 5 8 12 + diff --git a/Tools/generate-docc-reference/Extensions/ArgumentParser+Markdown.swift b/Tools/generate-docc-reference/Extensions/ArgumentParser+Markdown.swift index 7d44e69e1..856715e81 100644 --- a/Tools/generate-docc-reference/Extensions/ArgumentParser+Markdown.swift +++ b/Tools/generate-docc-reference/Extensions/ArgumentParser+Markdown.swift @@ -100,16 +100,16 @@ extension CommandInfoV0 { } } - if let extendedDiscussion = self.extendedDiscussion { - result += "\(extendedDiscussion)\n\n" - } - for subcommand in self.subcommands ?? [] { result += subcommand.toMarkdown( path + [self.commandName], markdownStyle: markdownStyle) + "\n\n" } + if let extendedDiscussion = self.extendedDiscussion { + result += "\(extendedDiscussion)\n\n" + } + return result }