@@ -87,7 +87,13 @@ static int PrintParserHelp(string[] args)
8787
8888 if ( args . Length == 2 && args [ 0 ] . Equals ( "help" , StringComparison . OrdinalIgnoreCase ) )
8989 {
90- Console . Error . Write ( CaptureParserHelp ( new [ ] { args [ 1 ] , "--help" } ) ) ;
90+ Console . Error . Write ( RenderVerbHelp ( args [ 1 ] , new [ ] { args [ 1 ] , "--help" } ) ) ;
91+ return 0 ;
92+ }
93+
94+ if ( args . Length >= 2 && FindVerbType ( args [ 0 ] ) is not null && args . Skip ( 1 ) . Any ( IsMainHelpRequest ) )
95+ {
96+ Console . Error . Write ( RenderVerbHelp ( args [ 0 ] , args ) ) ;
9197 return 0 ;
9298 }
9399
@@ -97,7 +103,7 @@ static int PrintParserHelp(string[] args)
97103 return 0 ;
98104 }
99105
100- Console . Error . Write ( CaptureParserHelp ( args ) ) ;
106+ Console . Error . Write ( RenderHelp ( args ) ) ;
101107 return 1 ;
102108 }
103109
@@ -219,6 +225,14 @@ static string GetVerbName(Type verbType) =>
219225 verbType . GetCustomAttribute < VerbAttribute > ( ) ? . Name
220226 ?? throw new InvalidOperationException ( $ "Missing VerbAttribute on { verbType . FullName } .") ;
221227
228+ static Type ? FindVerbType ( string verbName ) =>
229+ AllVerbTypes . FirstOrDefault ( type =>
230+ string . Equals ( GetVerbName ( type ) , verbName , StringComparison . OrdinalIgnoreCase ) ) ;
231+
232+ static string GetVerbHelpText ( Type verbType ) =>
233+ verbType . GetCustomAttribute < VerbAttribute > ( ) ? . HelpText
234+ ?? "" ;
235+
222236 static void AppendMainHelpBlock ( StringBuilder builder )
223237 {
224238 var help = new HelpText
@@ -267,11 +281,67 @@ static void AppendHelpBlock(StringBuilder builder, string title, string[] args)
267281 builder . AppendLine ( $ "## { title } ") ;
268282 builder . AppendLine ( ) ;
269283 builder . AppendLine ( "```text" ) ;
270- builder . Append ( CaptureParserHelp ( args , forDocumentation : true ) ) ;
284+ builder . Append ( RenderVerbHelp ( title , args , forDocumentation : true ) ) ;
271285 builder . AppendLine ( "```" ) ;
272286 builder . AppendLine ( ) ;
273287 }
274288
289+ static string RenderHelp ( string [ ] args , bool forDocumentation = false )
290+ {
291+ if ( args . Length > 0 )
292+ {
293+ var firstArg = args [ 0 ] ;
294+ if ( ! firstArg . StartsWith ( "-" , StringComparison . Ordinal ) && FindVerbType ( firstArg ) is not null )
295+ return RenderVerbHelp ( firstArg , args , forDocumentation ) ;
296+ }
297+
298+ return CaptureParserHelp ( args , forDocumentation ) ;
299+ }
300+
301+ static string RenderVerbHelp ( string verbName , string [ ] args , bool forDocumentation = false )
302+ {
303+ var verbType = FindVerbType ( verbName ) ;
304+ if ( verbType is null )
305+ return CaptureParserHelp ( args , forDocumentation ) ;
306+
307+ var builder = new StringBuilder ( ) ;
308+ builder . AppendLine ( forDocumentation ? GetDocumentationVersionLine ( ) : GetVersionLine ( ) ) ;
309+ builder . AppendLine ( ) ;
310+ builder . AppendLine ( $ "{ GetVerbName ( verbType ) } ") ;
311+ var helpText = GetVerbHelpText ( verbType ) ;
312+ if ( ! string . IsNullOrWhiteSpace ( helpText ) )
313+ builder . AppendLine ( $ " { helpText } ") ;
314+ builder . AppendLine ( ) ;
315+
316+ var parserHelp = CaptureParserHelp ( args , forDocumentation )
317+ . Replace ( forDocumentation ? GetDocumentationVersionLine ( ) : GetVersionLine ( ) , "" , StringComparison . Ordinal )
318+ . TrimStart ( ) ;
319+ if ( ! string . IsNullOrWhiteSpace ( parserHelp ) )
320+ {
321+ builder . AppendLine ( "Options:" ) ;
322+ builder . Append ( NormalizeIndentedBlock ( parserHelp ) ) ;
323+ }
324+
325+ return builder . ToString ( ) ;
326+ }
327+
328+ static string NormalizeIndentedBlock ( string text )
329+ {
330+ var builder = new StringBuilder ( ) ;
331+ foreach ( var line in text . Replace ( "\r \n " , "\n " ) . Split ( '\n ' ) )
332+ {
333+ if ( line . Length == 0 )
334+ continue ;
335+
336+ var normalizedLine = line . StartsWith ( " " , StringComparison . Ordinal )
337+ ? line [ 2 ..]
338+ : line . TrimStart ( ) ;
339+ builder . Append ( " " ) ;
340+ builder . AppendLine ( normalizedLine . TrimEnd ( ) ) ;
341+ }
342+ return builder . ToString ( ) . TrimEnd ( ) + Environment . NewLine ;
343+ }
344+
275345 static string CaptureParserHelp ( string [ ] args , bool forDocumentation = false )
276346 {
277347 var result = DocumentationParser . ParseArguments ( args , AllVerbTypes ) ;
0 commit comments