@@ -16,12 +16,17 @@ It finds the selected command and prints its help.
1616*/
1717help-command_ path / Path arguments / List --ui / Ui :
1818 command / Command := path .last
19+ show-all := false
1920
2021 for i := 0 ; i < arguments .size ; i ++:
2122 argument := arguments [ i ]
2223 if argument == "--" : break
2324
24- // Simply drop all options.
25+ if argument == "--all" :
26+ show-all = true
27+ continue
28+
29+ // Simply drop all other options.
2530 if argument .starts-with "-" :
2631 continue
2732
@@ -32,7 +37,24 @@ help-command_ path/Path arguments/List --ui/Ui:
3237 command = subcommand
3338 path += command
3439
35- emit-help_ path --ui = ui
40+ if show-all :
41+ emit-help-all_ path --ui = ui
42+ else:
43+ emit-help_ path --ui = ui
44+
45+ /**
46+ Emits the help for all commands in the subtree rooted at the given command.
47+
48+ The command is identified by the $path where the command is the last element.
49+ */
50+ emit-help-all_ path / Path --ui / Ui :
51+ ui .emit --kind = Ui .RESULT
52+ --structured =:
53+ build-json-help-all_ path
54+ --text =:
55+ generator := HelpGenerator path
56+ generator .build-all-commands
57+ generator .to-string
3658
3759/**
3860Emits the help for the given command.
@@ -48,6 +70,35 @@ emit-help_ path/Path --ui/Ui:
4870 generator .build-all
4971 generator .to-string
5072
73+ build-json-help-all_ path / Path -> Map :
74+ return build-json-command-tree_ path .last --is-root = ( path .size == 1 )
75+
76+ build-json-command-tree_ command / Command --is-root / bool= false -> Map :
77+ sub-list := []
78+ sorted := command .subcommands_ .sort : | a / Command b / Command | a .name .compare-to b .name
79+ sorted .do : | sub / Command |
80+ if sub .is-hidden_ : continue .do
81+ sub-list .add ( build-json-command-tree_ sub )
82+
83+ if is-root :
84+ has-help := false
85+ has-completion := false
86+ command .subcommands_ .do : | sub / Command |
87+ if sub .name == "help" : has-help = true
88+ sub .aliases_ .do : if it == "help" : has-help = true
89+ if sub .name == "completion" : has-completion = true
90+ sub .aliases_ .do : if it == "completion" : has-completion = true
91+ if not has-help :
92+ sub-list .add { "name" : "help" , "help" : "Show help for a command." , "subcommands" : [] }
93+ if not has-completion :
94+ sub-list .add { "name" : "completion" , "help" : "Generate shell completion scripts." , "subcommands" : [] }
95+
96+ return {
97+ "name" : command .name ,
98+ "help" : command .short-help ,
99+ "subcommands" : sub-list ,
100+ }
101+
51102build-json-help_ path / Path -> Map :
52103 // Local block to build json objects for the given command.
53104 // Adds the converted json object to the out-map.
@@ -254,6 +305,53 @@ class HelpGenerator:
254305 sorted-commands := commands-and-help .sort : | a / List b / List | a [ 0 ] .compare-to b [ 0 ]
255306 write-table_ sorted-commands --indentation = 2
256307
308+ /**
309+ Builds a hierarchical summary of all commands in the subtree.
310+
311+ Recursively lists all subcommands with indentation showing nesting.
312+ Hidden commands are excluded. At root level, auto-added 'help' and
313+ 'completion' entries are included.
314+ */
315+ build-all-commands -> none :
316+ rows := []
317+ collect-commands-recursive_ command_ rows --indent = 0 --is-root = is-root-command_
318+ if rows .is-empty : return
319+ write-table_ rows
320+
321+ /**
322+ Collects all commands recursively into $rows as [indented-name, short-help] pairs.
323+ */
324+ collect-commands-recursive_ command / Command rows / List --indent / int --is-root / bool= false -> none :
325+ // Each entry is [name, help, subcommand-or-null].
326+ entries := []
327+ command .subcommands_ .do : | subcommand / Command |
328+ if subcommand .is-hidden_ : continue .do
329+ entries .add [ subcommand .name , subcommand .short-help , subcommand ]
330+
331+ if is-root :
332+ has-help := false
333+ has-completion := false
334+ command .subcommands_ .do : | sub / Command |
335+ if sub .name == "help" : has-help = true
336+ sub .aliases_ .do : if it == "help" : has-help = true
337+ if sub .name == "completion" : has-completion = true
338+ sub .aliases_ .do : if it == "completion" : has-completion = true
339+ if not has-help :
340+ entries .add [ "help" , "Show help for a command." , null ]
341+ if not has-completion :
342+ entries .add [ "completion" , "Generate shell completion scripts." , null ]
343+
344+ sorted := entries .sort : | a / List b / List |
345+ ( a [ 0 ] as string ) .compare-to ( b [ 0 ] as string )
346+
347+ prefix := " " * indent
348+ sorted .do : | entry / List |
349+ name := entry [ 0 ] as string
350+ help-str := entry [ 1 ] as string
351+ rows .add [ "$ prefix$ name " , help-str ]
352+ if entry [ 2 ] :
353+ collect-commands-recursive_ ( entry [ 2 ] as Command ) rows --indent = ( indent + 2 )
354+
257355 /**
258356 Builds the local options section.
259357
0 commit comments