@@ -11,33 +11,37 @@ open FSharp.Reflection
1111/// that is an F# discriminated union. It can then be used to parse command line arguments
1212/// or XML configuration.
1313[<NoEquality; NoComparison; AutoSerializable( false ) >]
14- type ArgumentParser < 'Template when 'Template :> IArgParserTemplate > private ( argInfo : UnionArgInfo , ? programName : string , ? description : string , ? errorHandler : IExiter ) =
14+ type ArgumentParser < 'Template when 'Template :> IArgParserTemplate >
15+ internal ( argInfo : UnionArgInfo, ?programName : string, ?description : string,
16+ ?usageStringCharacterWidth : int, ?errorHandler : IExiter) =
17+
1518 // memoize parser generation for given template type
1619 static let argInfoLazy = lazy ( preComputeUnionArgInfo< 'Template> ())
1720
21+ let _usageStringCharacterWidth = defaultArg usageStringCharacterWidth 80
1822 let _programName = match programName with Some pn -> pn | None -> currentProgramName.Value
1923 let errorHandler = match errorHandler with Some e -> e | None -> new ExceptionExiter() :> _
2024
21- let mkUsageString argInfo msgOpt = printUsage argInfo _ programName description msgOpt |> String.build
22-
25+ let mkUsageString argInfo msgOpt = printUsage argInfo _ programName _ usageStringCharacterWidth msgOpt |> StringExpr.build
2326
2427 let (| ParserExn | _ |) ( e : exn ) =
2528 match e with
2629 // do not display usage for App.Config parameter errors
27- | ParseError ( msg, id , _) when id <> ErrorCode.CommandLine -> Some( id , msg)
30+ | ParseError ( msg, ErrorCode.AppSettings , _) -> Some( ErrorCode.AppSettings , msg)
2831 | ParseError ( msg, id, aI) -> Some ( id, mkUsageString aI ( Some msg))
29- | HelpText aI -> Some ( ErrorCode.HelpText, mkUsageString aI None )
32+ | HelpText aI -> Some ( ErrorCode.HelpText, mkUsageString aI description )
3033 | _ -> None
3134
3235 /// <summary >
3336 /// Creates a new parser instance based on supplied F# union template.
3437 /// </summary >
3538 /// <param name =" programName " >Program identifier, e.g. 'cat'. Defaults to the current executable name.</param >
3639 /// <param name =" description " >Program description placed at the top of the usage string.</param >
40+ /// <param name =" usageStringCharacterWidth " >Text width used when formatting the usage string. Defaults to 80 chars.</param >
3741 /// <param name =" errorHandler " >The implementation of IExiter used for error handling. Exception is default.</param >
38- new (? programName : string , ? description : string , ? errorHandler : IExiter ) =
42+ new (? programName : string , ? description : string , ? usageStringCharacterWidth : int , ? errorHandler : IExiter ) =
3943 new ArgumentParser< 'Template>( argInfoLazy.Value, ?programName = programName,
40- ?description = description, ?errorHandler = errorHandler)
44+ ?usageStringCharacterWidth = usageStringCharacterWidth , ? description = description, ?errorHandler = errorHandler)
4145
4246 /// Gets the help flags specified for the CLI parser
4347 member __.HelpFlags = argInfo.HelpParam.Flags
@@ -64,11 +68,11 @@ type ArgumentParser<'Template when 'Template :> IArgParserTemplate> private (arg
6468 let inputs = match inputs with None -> getEnvironmentCommandLineArgs () | Some args -> args
6569
6670 try
67- let cliResults = parseCommandLine argInfo _ programName description errorHandler raiseOnUsage ignoreUnrecognized inputs
71+ let cliResults = parseCommandLine argInfo _ programName description _ usageStringCharacterWidth errorHandler raiseOnUsage ignoreUnrecognized inputs
6872 let ignoreMissing = ( cliResults.IsUsageRequested && not raiseOnUsage) || ignoreMissing
6973 let results = postProcessResults argInfo ignoreMissing None ( Some cliResults)
7074
71- new ParseResult< 'Template>( argInfo, results, mkUsageString argInfo , errorHandler)
75+ new ParseResult< 'Template>( argInfo, results, _ programName , description , _ usageStringCharacterWidth , errorHandler)
7276
7377 with ParserExn ( errorCode, msg) -> errorHandler.Exit ( msg, errorCode)
7478
@@ -82,7 +86,7 @@ type ArgumentParser<'Template when 'Template :> IArgParserTemplate> private (arg
8286 let appSettingsResults = parseKeyValueConfig configurationReader argInfo
8387 let results = postProcessResults argInfo ignoreMissing ( Some appSettingsResults) None
8488
85- new ParseResult< 'Template>( argInfo, results, mkUsageString argInfo , errorHandler)
89+ new ParseResult< 'Template>( argInfo, results, _ programName , description , _ usageStringCharacterWidth , errorHandler)
8690
8791 with ParserExn ( errorCode, msg) -> errorHandler.Exit ( msg, errorCode)
8892
@@ -102,10 +106,10 @@ type ArgumentParser<'Template when 'Template :> IArgParserTemplate> private (arg
102106
103107 try
104108 let appSettingsResults = parseKeyValueConfig configurationReader argInfo
105- let cliResults = parseCommandLine argInfo _ programName description errorHandler raiseOnUsage ignoreUnrecognized inputs
109+ let cliResults = parseCommandLine argInfo _ programName description _ usageStringCharacterWidth errorHandler raiseOnUsage ignoreUnrecognized inputs
106110 let results = postProcessResults argInfo ignoreMissing ( Some appSettingsResults) ( Some cliResults)
107111
108- new ParseResult< 'Template>( argInfo, results, mkUsageString argInfo , errorHandler)
112+ new ParseResult< 'Template>( argInfo, results, _ programName , description , _ usageStringCharacterWidth , errorHandler)
109113
110114 with ParserExn ( errorCode, msg) -> errorHandler.Exit ( msg, errorCode)
111115
@@ -134,11 +138,7 @@ type ArgumentParser<'Template when 'Template :> IArgParserTemplate> private (arg
134138 /// </summary >
135139 /// <param name =" inputs " >Argument input sequence.</param >
136140 member __.ToParseResult ( inputs : seq < 'Template >) : ParseResult < 'Template > =
137- mkParseResultFromValues argInfo errorHandler ( mkUsageString argInfo) inputs
138-
139- /// <summary >Returns the usage string.</summary >
140- /// <param name =" message " >The message to be displayed on top of the usage string.</param >
141- member __.Usage (? message : string ) : string = mkUsageString argInfo message
141+ mkParseResultFromValues argInfo errorHandler _ usageStringCharacterWidth _ programName description inputs
142142
143143 /// <summary >
144144 /// Gets a subparser associated with specific subcommand instance
@@ -174,26 +174,37 @@ type ArgumentParser<'Template when 'Template :> IArgParserTemplate> private (arg
174174 let uci = expr2Uci ctorExpr
175175 argInfo.Cases.[ uci.Tag]. ToArgumentCaseInfo()
176176
177+ /// <summary >Formats a usage string for the argument parser.</summary >
178+ /// <param name =" message " >The message to be displayed on top of the usage string.</param >
179+ /// <param name =" programName " >Override the default program name settings.</param >
180+ /// <param name =" usageStringCharacterWidth " >Text width used when formatting the usage string.</param >
181+ member __.PrintUsage (? message : string , ? programName : string , ? usageStringCharacterWidth : int ) : string =
182+ let programName = defaultArg programName _ programName
183+ let usageStringCharacterWidth = defaultArg usageStringCharacterWidth _ usageStringCharacterWidth
184+ printUsage argInfo programName usageStringCharacterWidth message |> StringExpr.build
185+
177186 /// <summary >
178187 /// Prints command line syntax. Useful for generating documentation.
179188 /// </summary >
180189 /// <param name =" programName " >Program name identifier placed at start of syntax string</param >
181- member __.PrintCommandLineSyntax (? programName : string ) : string =
190+ /// <param name =" usageStringCharacterWidth " >Text width used when formatting the usage string.</param >
191+ member __.PrintCommandLineSyntax (? programName : string , ? usageStringCharacterWidth : int ) : string =
182192 let programName = defaultArg programName _ programName
183- printCommandLineSyntax argInfo programName |> String.build
193+ let usageStringCharacterWidth = defaultArg usageStringCharacterWidth _ usageStringCharacterWidth
194+ printCommandLineSyntax argInfo " " usageStringCharacterWidth programName |> StringExpr.build
184195
185196 /// <summary >Prints parameters in command line format. Useful for argument string generation.</summary >
186- member __.PrintCommandLine ( args : 'Template list ) : string [] =
197+ member __.PrintCommandLineArguments ( args : 'Template list ) : string [] =
187198 printCommandLineArgs argInfo ( Seq.cast args) |> Seq.toArray
188199
189200 /// <summary >Prints parameters in command line format. Useful for argument string generation.</summary >
190- member __.PrintCommandLineFlat ( args : 'Template list ) : string =
191- __. PrintCommandLine args |> flattenCliTokens
201+ member __.PrintCommandLineArgumentsFlat ( args : 'Template list ) : string =
202+ __. PrintCommandLineArguments args |> flattenCliTokens
192203
193204 /// <summary >Prints parameters in App.Config format.</summary >
194205 /// <param name =" args " >The parameters that fill out the XML document.</param >
195206 /// <param name =" printComments " >Print XML comments over every configuration entry.</param >
196- member __.PrintAppSettings ( args : 'Template list , ? printComments : bool ) : string =
207+ member __.PrintAppSettingsArguments ( args : 'Template list , ? printComments : bool ) : string =
197208 let printComments = defaultArg printComments true
198209 let xmlDoc = printAppSettings argInfo printComments args
199210 use writer = { new System.IO.StringWriter() with member __.Encoding = System.Text.Encoding.UTF8 }
@@ -212,14 +223,21 @@ type ArgumentParser =
212223 /// </summary >
213224 /// <param name =" programName " >Program identifier, e.g. 'cat'. Defaults to the current executable name.</param >
214225 /// <param name =" description " >Program description placed at the top of the usage string.</param >
226+ /// <param name =" usageStringCharacterWidth " >Text width used when formatting the usage string. Defaults to 80 chars.</param >
215227 /// <param name =" errorHandler " >The implementation of IExiter used for error handling. Exception is default.</param >
216- static member Create < 'Template when 'Template :> IArgParserTemplate >(? programName : string , ? description : string , ? errorHandler : IExiter ) =
217- new ArgumentParser< 'Template>( ?programName = programName, ?description = description, ?errorHandler = errorHandler)
228+ static member Create < 'Template when 'Template :> IArgParserTemplate >(? programName : string , ? description : string , ? usageStringCharacterWidth : int , ? errorHandler : IExiter ) =
229+ new ArgumentParser< 'Template>( ?programName = programName, ?description = description, ?errorHandler = errorHandler, ?usageStringCharacterWidth = usageStringCharacterWidth )
218230
219231
220232[<AutoOpen>]
221233module ArgumentParserUtils =
222-
234+
235+ type ParseResult < 'Template when 'Template :> IArgParserTemplate > with
236+ member r.Parser =
237+ new ArgumentParser< 'Template>( r.ArgInfo, r.ProgramName, ?description = r.Description,
238+ usageStringCharacterWidth = r.CharacterWidth,
239+ errorHandler = r.ErrorHandler)
240+
223241 /// converts a sequence of inputs to a ParseResult instance
224242 let toParseResults ( inputs : seq < 'Template >) : ParseResult < 'Template > =
225243 ArgumentParser.Create< 'Template>() .ToParseResult( inputs)
0 commit comments