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
Add API for titling an option group #492
Changes from 7 commits
772a551
7312820
fb5c3e9
a5f13f2
53911ea
abec9d7
a2727fd
47188c7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,6 +51,7 @@ internal struct HelpGenerator { | |
case positionalArguments | ||
case subcommands | ||
case options | ||
case title(String) | ||
|
||
var description: String { | ||
switch self { | ||
|
@@ -60,6 +61,8 @@ internal struct HelpGenerator { | |
return "Subcommands" | ||
case .options: | ||
return "Options" | ||
case .title(let name): | ||
return name | ||
} | ||
} | ||
} | ||
|
@@ -136,6 +139,10 @@ internal struct HelpGenerator { | |
|
||
var positionalElements: [Section.Element] = [] | ||
var optionElements: [Section.Element] = [] | ||
|
||
// Simulate an ordered dictionary using a dictionary and array for ordering. | ||
var titledSections: [String: [Section.Element]] = [:] | ||
var sectionTitles: [String] = [] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this needed? It seems like a duplicate of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NVM this is so they are sorted. A comment about this would be nice! |
||
|
||
/// Start with a full slice of the ArgumentSet so we can peel off one or | ||
/// more elements at a time. | ||
|
@@ -183,9 +190,15 @@ internal struct HelpGenerator { | |
} | ||
|
||
let element = Section.Element(label: synopsis, abstract: description, discussion: arg.help.discussion) | ||
if case .positional = arg.kind { | ||
switch (arg.kind, arg.help.parentTitle) { | ||
case (_, let sectionTitle) where !sectionTitle.isEmpty: | ||
if !titledSections.keys.contains(sectionTitle) { | ||
sectionTitles.append(sectionTitle) | ||
} | ||
titledSections[sectionTitle, default: []].append(element) | ||
case (.positional, _): | ||
positionalElements.append(element) | ||
} else { | ||
default: | ||
optionElements.append(element) | ||
} | ||
} | ||
|
@@ -203,8 +216,16 @@ internal struct HelpGenerator { | |
abstract: command.configuration.abstract) | ||
} | ||
|
||
// Combine the compiled groups in this order: | ||
// - arguments | ||
// - named sections | ||
// - options/flags | ||
// - subcommands | ||
Comment on lines
+219
to
+223
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @rauhul @ethan-kusters Does this seem like the correct order? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah this makes sense to me! |
||
return [ | ||
Section(header: .positionalArguments, elements: positionalElements), | ||
] + sectionTitles.map { name in | ||
Section(header: .title(name), elements: titledSections[name, default: []]) | ||
} + [ | ||
Section(header: .options, elements: optionElements), | ||
Section(header: .subcommands, elements: subcommandElements), | ||
] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -132,7 +132,6 @@ extension StringProtocol where SubSequence == Substring { | |
/// // 3 | ||
/// "bar".editDistance(to: "baz") | ||
/// // 1 | ||
|
||
func editDistance(to target: String) -> Int { | ||
let rows = self.count | ||
let columns = target.count | ||
|
@@ -239,4 +238,8 @@ extension StringProtocol where SubSequence == Substring { | |
guard lines.count == 2 else { return lines.joined(separator: "") } | ||
return "\(lines[0])\n\(lines[1].indentingEachLine(by: n))" | ||
} | ||
|
||
var nilIfEmpty: Self? { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note: this is called |
||
isEmpty ? nil : self | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this still, SAP isn't ABI stable and the above initializer is source compatible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eh, well very very minimally source breaking if someone ever used a point free version of the function:
OptionGroup.init(visibility:)
I really doubt this is the case though.