@@ -51,59 +51,31 @@ trait CliCommand:
51
51
end distill
52
52
53
53
/** Creates a help message for a subset of options based on cond */
54
- protected def availableOptionsMsg (cond : Setting [? ] => Boolean )(using settings : ConcreteSettings )(using SettingsState ): String =
55
- val ss = (settings.allSettings filter cond).toList sortBy (_.name)
56
- val maxNameWidth = 30
57
- val nameWidths = ss.map(_.name.length).filter(_ < maxNameWidth)
58
- val width = if nameWidths.nonEmpty then nameWidths.max else maxNameWidth
59
- val terminalWidth = settings.pageWidth.value
60
- val (nameWidth, descriptionWidth) = {
61
- val w1 =
62
- if width < maxNameWidth then width
63
- else maxNameWidth
64
- val w2 =
65
- if terminalWidth < w1 + maxNameWidth then 0
66
- else terminalWidth - w1 - 1
67
- (w1, w2)
68
- }
69
- def formatName (name : String ) =
70
- if name.length <= nameWidth then (" %-" + nameWidth + " s" ) format name
71
- else (name + " \n %-" + nameWidth + " s" ) format " "
72
- def formatDescription (text : String ): String =
73
- if descriptionWidth == 0 then text
74
- else if text.length < descriptionWidth then text
75
- else {
76
- val inx = text.substring(0 , descriptionWidth).lastIndexOf(" " )
77
- if inx < 0 then text
78
- else
79
- val str = text.substring(0 , inx)
80
- s " ${str}\n ${formatName(" " )} ${formatDescription(text.substring(inx + 1 ))}"
81
- }
82
- def formatSetting (name : String , value : String ) =
83
- if (value.nonEmpty)
84
- // the format here is helping to make empty padding and put the additional information exactly under the description.
85
- s " \n ${formatName(" " )} $name: $value. "
86
- else
87
- " "
88
- def helpStr (s : Setting [? ]) =
54
+ protected def availableOptionsMsg (p : Setting [? ] => Boolean )(using settings : ConcreteSettings )(using SettingsState ): String =
55
+ // result is (Option Name, descrption\ndefault: value\nchoices: x, y, z
56
+ def help (s : Setting [? ]): (String , String ) =
57
+ // For now, skip the default values that do not make sense for the end user, such as 'false' for the version command.
89
58
def defaultValue = s.default match
90
59
case _ : Int | _ : String => s.default.toString
91
- case _ =>
92
- // For now, skip the default values that do not make sense for the end user.
93
- // For example 'false' for the version command.
94
- " "
95
- s " ${formatName(s.name)} ${formatDescription(shortHelp(s))}${formatSetting(" Default" , defaultValue)}${formatSetting(" Choices" , s.legalChoices)}"
96
- ss.map(helpStr).mkString(" " , " \n " , s " \n ${formatName(" @<file>" )} ${formatDescription(" A text file containing compiler arguments (options and source files)." )}\n " )
60
+ case _ => " "
61
+ val info = List (shortHelp(s), if defaultValue.nonEmpty then s " Default $defaultValue" else " " , if s.legalChoices.nonEmpty then s " Choices ${s.legalChoices}" else " " )
62
+ (s.name, info.filter(_.nonEmpty).mkString(" \n " ))
63
+ end help
64
+
65
+ val ss = settings.allSettings.filter(p).toList.sortBy(_.name)
66
+ val formatter = Columnator (" " , " " , maxField = 30 )
67
+ val fresh = ContextBase ().initialCtx.fresh.setSettings(summon[SettingsState ])
68
+ formatter(List (ss.map(help) :+ (" @<file>" , " A text file containing compiler arguments (options and source files)." )))(using fresh)
97
69
end availableOptionsMsg
98
70
99
71
protected def shortUsage : String = s " Usage: $cmdName <options> <source files> "
100
72
101
73
protected def createUsageMsg (label : String , shouldExplain : Boolean , cond : Setting [? ] => Boolean )(using settings : ConcreteSettings )(using SettingsState ): String =
102
74
val prefix = List (
103
75
Some (shortUsage),
104
- Some (explainAdvanced) filter (_ => shouldExplain),
76
+ Some (explainAdvanced). filter(_ => shouldExplain),
105
77
Some (label + " options include:" )
106
- ).flatten mkString " \n "
78
+ ).flatten. mkString( " \n " )
107
79
108
80
prefix + " \n " + availableOptionsMsg(cond)
109
81
@@ -140,7 +112,7 @@ trait CliCommand:
140
112
/** Used for the formatted output of -Xshow-phases */
141
113
protected def phasesMessage (using Context ): String =
142
114
val phases = new Compiler ().phases
143
- val formatter = Columnator (" phase name" , " description" , maxField = 25 , separation = 2 )
115
+ val formatter = Columnator (" phase name" , " description" , maxField = 25 )
144
116
formatter(phases.map(mega => mega.map(p => (p.phaseName, p.description))))
145
117
146
118
/** Provide usage feedback on argument summary, assuming that all settings
@@ -174,7 +146,7 @@ trait CliCommand:
174
146
def padLeft (width : Int ): String = StringBuilder ().tap(_.append(" " * (width - s.length)).append(s)).toString
175
147
176
148
// Formatting for -help and -Vphases in two columns, handling long field1 and wrapping long field2
177
- class Columnator (heading1 : String , heading2 : String , maxField : Int , separation : Int = 1 ):
149
+ class Columnator (heading1 : String , heading2 : String , maxField : Int , separation : Int = 2 ):
178
150
def apply (texts : List [List [(String , String )]])(using Context ): String = StringBuilder ().tap(columnate(_, texts)).toString
179
151
180
152
private def columnate (sb : StringBuilder , texts : List [List [(String , String )]])(using Context ): Unit =
@@ -187,21 +159,15 @@ trait CliCommand:
187
159
val field1 = maxField.min(texts.flatten.map(_._1.length).filter(_ < maxField).max) // widest field under maxField
188
160
val field2 = if field1 + separation + maxField < maxCol then maxCol - field1 - separation else 0 // skinny window -> terminal wrap
189
161
val separator = " " * separation
190
- def formatField1 (text : String ): String = if text.length <= field1 then text.padLeft(field1) else EOL + " " .padLeft(field1)
162
+ def formatField1 (text : String ): String = if text.length <= field1 then text.padLeft(field1) else text + EOL + " " .padLeft(field1)
191
163
def formatField2 (text : String ): String =
192
- def loopOverField2 (fld : String ): String =
193
- if field2 == 0 || fld.length <= field2 then fld
164
+ def loopOverField2 (fld : String ): List [ String ] =
165
+ if field2 == 0 || fld.length <= field2 then List ( fld)
194
166
else
195
167
fld.lastIndexOf(" " , field2) match
196
- case - 1 => fld
197
- case i =>
198
- val (prefix, rest) = fld.splitAt(i)
199
- s " ${prefix}${EOL }${formatField1(" " )}${separator}${loopOverField2(rest.trim)}"
200
- def loopOverFields2 (rest : List [String ]): String =
201
- rest match
202
- case h :: t => loopOverField2(h.trim) + loopOverFields2(t)
203
- case Nil => " "
204
- loopOverFields2(text.split(" \n " ).toList)
168
+ case - 1 => List (fld)
169
+ case i => val (prefix, rest) = fld.splitAt(i) ; prefix :: loopOverField2(rest.trim)
170
+ text.split(" \n " ).toList.flatMap(loopOverField2).filter(_.nonEmpty).mkString(EOL + " " .padLeft(field1) + separator)
205
171
end formatField2
206
172
def format (first : String , second : String , index : Int , colorPicker : Int => String => Highlight ) =
207
173
sb.append(colorPicker(index)(formatField1(first)).show)
0 commit comments