@@ -136,6 +136,11 @@ final class main(maxLineLength: Int) extends MainAnnotation:
136
136
else
137
137
None
138
138
139
+ def isArgName (arg : String ): Boolean =
140
+ val isFullName = arg.startsWith(argMarker)
141
+ val isShortName = arg.startsWith(shortArgMarker) && arg.length == 2 && shortNameIsValid(arg(1 ))
142
+ isFullName || isShortName
143
+
139
144
def recurse (remainingArgs : Seq [String ], pa : mutable.Queue [String ], bna : Seq [(String , String )], ia : Seq [String ]): (mutable.Queue [String ], Seq [(String , String )], Seq [String ]) =
140
145
remainingArgs match {
141
146
case Seq () =>
@@ -165,11 +170,6 @@ final class main(maxLineLength: Int) extends MainAnnotation:
165
170
errors += msg
166
171
() => throw new AssertionError (" trying to get invalid argument" )
167
172
168
- private def isArgName (arg : String ): Boolean =
169
- val isFullName = arg.startsWith(argMarker)
170
- val isShortName = arg.startsWith(shortArgMarker) && arg.length == 2 && shortNameIsValid(arg(1 ))
171
- isFullName || isShortName
172
-
173
173
private def nameIsValid (name : String ): Boolean =
174
174
name.length > 0 // TODO add more checks for illegal characters
175
175
@@ -181,57 +181,58 @@ final class main(maxLineLength: Int) extends MainAnnotation:
181
181
case Some (t) => () => t
182
182
case None => error(s " invalid argument for $argName: $arg" )
183
183
184
- private def argsUsage : Seq [String ] =
185
- for ((infos, kind) <- parameterInfoss.zip(argKinds))
186
- yield {
187
- val canonicalName = argMarker + infos.name
188
- val shortNames = getShortNames(infos).map(shortArgMarker + _)
189
- val alternativeNames = getAlternativeNames(infos).map(argMarker + _)
190
- val namesPrint = (canonicalName +: alternativeNames ++: shortNames).mkString(" [" , " | " , " ]" )
191
-
192
- kind match {
193
- case ArgumentKind .SimpleArgument => s " $namesPrint < ${infos.typeName}> "
194
- case ArgumentKind .OptionalArgument => s " [ $namesPrint < ${infos.typeName}>] "
195
- case ArgumentKind .VarArgument => s " [< ${infos.typeName}> [< ${infos.typeName}> [...]]] "
196
- }
197
- }
198
-
199
- private def wrapLongLine (line : String , maxLength : Int ): List [String ] = {
200
- def recurse (s : String , acc : Vector [String ]): Seq [String ] =
201
- val lastSpace = s.trim.nn.lastIndexOf(' ' , maxLength)
202
- if ((s.length <= maxLength) || (lastSpace < 0 ))
203
- acc :+ s
204
- else {
205
- val (shortLine, rest) = s.splitAt(lastSpace)
206
- recurse(rest.trim.nn, acc :+ shortLine)
207
- }
208
-
209
- recurse(line, Vector ()).toList
210
- }
184
+ private def usage (): Unit =
185
+ def argsUsage : Seq [String ] =
186
+ for ((infos, kind) <- parameterInfoss.zip(argKinds))
187
+ yield {
188
+ val canonicalName = argMarker + infos.name
189
+ val shortNames = getShortNames(infos).map(shortArgMarker + _)
190
+ val alternativeNames = getAlternativeNames(infos).map(argMarker + _)
191
+ val namesPrint = (canonicalName +: alternativeNames ++: shortNames).mkString(" [" , " | " , " ]" )
211
192
212
- private def wrapArgumentUsages (argsUsage : Seq [String ], maxLength : Int ): Seq [String ] = {
213
- def recurse (args : Seq [String ], currentLine : String , acc : Vector [String ]): Seq [String ] =
214
- (args, currentLine) match {
215
- case (Nil , " " ) => acc
216
- case (Nil , l) => (acc :+ l)
217
- case (arg +: t, " " ) => recurse(t, arg, acc)
218
- case (arg +: t, l) if l.length + 1 + arg.length <= maxLength => recurse(t, s " $l $arg" , acc)
219
- case (arg +: t, l) => recurse(t, arg, acc :+ l)
193
+ kind match {
194
+ case ArgumentKind .SimpleArgument => s " $namesPrint < ${infos.typeName}> "
195
+ case ArgumentKind .OptionalArgument => s " [ $namesPrint < ${infos.typeName}>] "
196
+ case ArgumentKind .VarArgument => s " [< ${infos.typeName}> [< ${infos.typeName}> [...]]] "
197
+ }
220
198
}
221
199
222
- recurse(argsUsage, " " , Vector ()).toList
223
- }
200
+ def wrapArgumentUsages (argsUsage : Seq [String ], maxLength : Int ): Seq [String ] = {
201
+ def recurse (args : Seq [String ], currentLine : String , acc : Vector [String ]): Seq [String ] =
202
+ (args, currentLine) match {
203
+ case (Nil , " " ) => acc
204
+ case (Nil , l) => (acc :+ l)
205
+ case (arg +: t, " " ) => recurse(t, arg, acc)
206
+ case (arg +: t, l) if l.length + 1 + arg.length <= maxLength => recurse(t, s " $l $arg" , acc)
207
+ case (arg +: t, l) => recurse(t, arg, acc :+ l)
208
+ }
224
209
225
- private inline def shiftLines (s : Seq [String ], shift : Int ): String = s.map(" " * shift + _).mkString(" \n " )
210
+ recurse(argsUsage, " " , Vector ()).toList
211
+ }
226
212
227
- private def usage (): Unit =
228
213
val usageBeginning = s " Usage: $commandName "
229
214
val argsOffset = usageBeginning.length
230
215
val usages = wrapArgumentUsages(argsUsage, maxLineLength - argsOffset)
231
216
232
217
println(usageBeginning + usages.mkString(" \n " + " " * argsOffset))
218
+ end usage
233
219
234
220
private def explain (): Unit =
221
+ inline def shiftLines (s : Seq [String ], shift : Int ): String = s.map(" " * shift + _).mkString(" \n " )
222
+
223
+ def wrapLongLine (line : String , maxLength : Int ): List [String ] = {
224
+ def recurse (s : String , acc : Vector [String ]): Seq [String ] =
225
+ val lastSpace = s.trim.nn.lastIndexOf(' ' , maxLength)
226
+ if ((s.length <= maxLength) || (lastSpace < 0 ))
227
+ acc :+ s
228
+ else {
229
+ val (shortLine, rest) = s.splitAt(lastSpace)
230
+ recurse(rest.trim.nn, acc :+ shortLine)
231
+ }
232
+
233
+ recurse(line, Vector ()).toList
234
+ }
235
+
235
236
if (documentation.nonEmpty)
236
237
println(wrapLongLine(documentation, maxLineLength).mkString(" \n " ))
237
238
if (nameToParameterInfos.nonEmpty) {
@@ -268,6 +269,7 @@ final class main(maxLineLength: Int) extends MainAnnotation:
268
269
269
270
println(argDoc)
270
271
}
272
+ end explain
271
273
272
274
private def getAlternativeNames (paramInfos : ParameterInfos ): Seq [String ] =
273
275
val (valid, invalid) =
@@ -292,10 +294,6 @@ final class main(maxLineLength: Int) extends MainAnnotation:
292
294
for (name, canonicalNames) <- nameToCanonicalNames if canonicalNames.length > 1
293
295
do throw AssertionError (s " $name is used for multiple parameters: ${canonicalNames.mkString(" , " )}" )
294
296
295
- private def flagUnused (): Unit =
296
- for (remainingArg <- positionalArgs) error(s " unused argument: $remainingArg" )
297
- for (invalidArg <- invalidByNameArgs) error(s " unknown argument name: $invalidArg" )
298
-
299
297
override def argGetter [T ](name : String , optDefaultGetter : Option [() => T ])(using p : ArgumentParser [T ]): () => T =
300
298
argKinds += (if optDefaultGetter.nonEmpty then ArgumentKind .OptionalArgument else ArgumentKind .SimpleArgument )
301
299
val parameterInfos = nameToParameterInfos(name)
@@ -329,7 +327,8 @@ final class main(maxLineLength: Int) extends MainAnnotation:
329
327
() => (byNameGetters ++ positionalGetters).map(_())
330
328
331
329
override def run (f : => MainResultType ): Unit =
332
- flagUnused()
330
+ for (remainingArg <- positionalArgs) error(s " unused argument: $remainingArg" )
331
+ for (invalidArg <- invalidByNameArgs) error(s " unknown argument name: $invalidArg" )
333
332
checkNamesUnicity()
334
333
335
334
if args.contains(s " ${argMarker}help " ) then
0 commit comments