Skip to content

Commit a0e384b

Browse files
committed
Improve help DefaultHelpFormatter
Auto-adjust width of left column to avoid wrapping usages strings.
1 parent 6519b75 commit a0e384b

File tree

2 files changed

+33
-21
lines changed

2 files changed

+33
-21
lines changed

src/main/kotlin/ArgParser.kt

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -891,6 +891,9 @@ class DefaultHelpFormatter(
891891
val prologue: String? = null,
892892
val epilogue: String? = null
893893
) : HelpFormatter {
894+
val indent = " "
895+
val indentWidth = indent.codePointWidth()
896+
894897
override fun format(
895898
progName: String?,
896899
columns: Int,
@@ -918,9 +921,14 @@ class DefaultHelpFormatter(
918921
else -> optional
919922
}.add(value)
920923
}
921-
appendSection(sb, columns, "required", required)
922-
appendSection(sb, columns, "optional", optional)
923-
appendSection(sb, columns, "positional", positional)
924+
// Make left column as narrow as possible without wrapping any of the individual usages, though no wider than
925+
// half the screen.
926+
val usageColumns = (2 * indentWidth - 1 + (
927+
values.map { usageText(it).split(" ").map { it.length }.max() ?: 0 }.max() ?: 0)
928+
).coerceAtMost(columns / 2)
929+
appendSection(sb, usageColumns, columns, "required", required)
930+
appendSection(sb, usageColumns, columns, "optional", optional)
931+
appendSection(sb, usageColumns, columns, "positional", positional)
924932

925933
if (!epilogue.isNullOrEmpty()) {
926934
sb.append("\n")
@@ -932,24 +940,29 @@ class DefaultHelpFormatter(
932940
return sb.toString()
933941
}
934942

935-
private fun appendSection(sb: StringBuilder, columns: Int, name: String, values: List<HelpFormatter.Value>) {
936-
// TODO: make these configurable or smarter?
937-
val helpPos = columns * 3 / 10
938-
val indent = " "
939-
val indentWidth = indent.codePointWidth()
943+
private fun appendSection(
944+
sb: StringBuilder,
945+
usageColumns: Int,
946+
columns: Int,
947+
name: String,
948+
values: List<HelpFormatter.Value>
949+
) {
940950

941951
if (!values.isEmpty()) {
942952
sb.append("\n")
943953
sb.append("$name arguments:\n")
944954
for (value in values) {
945-
val left = value.usages.map { it.replace(' ', '\u00a0') }.joinToString(", ").wrapText(helpPos - indentWidth).prependIndent(indent)
946-
val right = value.help.wrapText(columns - helpPos - 2 * indentWidth).prependIndent(indent)
947-
sb.append(columnize(left, right, minWidths = intArrayOf(helpPos)))
955+
val left = usageText(value).wrapText(usageColumns - indentWidth).prependIndent(indent)
956+
val right = value.help.wrapText(columns - usageColumns - 2 * indentWidth).prependIndent(indent)
957+
sb.append(columnize(left, right, minWidths = intArrayOf(usageColumns)))
948958
sb.append("\n\n")
949959
}
950960
}
951961
}
952962

963+
private fun usageText(value: HelpFormatter.Value) =
964+
value.usages.map { it.replace(' ', '\u00a0') }.joinToString(", ")
965+
953966
private fun appendUsage(sb: StringBuilder, columns: Int, progName: String?, values: List<HelpFormatter.Value>) {
954967
val usageStart = "usage:${if (progName != null) " $progName" else ""} "
955968

src/test/kotlin/ArgParserTest.kt

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -851,26 +851,25 @@ Phasellus.
851851
852852
853853
required arguments:
854-
-o OUTPUT, directory in which all output should
855-
--output OUTPUT be generated
854+
-o OUTPUT, directory in which all output should
855+
--output OUTPUT be generated
856856
857857
858858
optional arguments:
859-
-h, --help show this help message and exit
859+
-h, --help show this help message and exit
860860
861-
-n, --dry-run don't do anything
861+
-n, --dry-run don't do anything
862862
863-
-I INCLUDE, search in this directory for header
864-
--include INCLU files
865-
DE
863+
-I INCLUDE, search in this directory for header
864+
--include INCLUDE files
866865
867-
-v, --verbose increase verbosity
866+
-v, --verbose increase verbosity
868867
869868
870869
positional arguments:
871-
SOURCE source file
870+
SOURCE source file
872871
873-
DEST destination file
872+
DEST destination file
874873
875874
876875

0 commit comments

Comments
 (0)