@@ -3,23 +3,25 @@ package cli
33import (
44 "context"
55 "fmt"
6- "io"
76 "maps"
87 "slices"
98 "sort"
9+ "strings"
1010
1111 "github.com/domonda/go-function"
1212)
1313
1414type SuperStringArgsDispatcher struct {
15- sub map [string ]* StringArgsDispatcher
16- loggers []StringArgsCommandLogger
15+ baseCommand string
16+ sub map [string ]* StringArgsDispatcher
17+ loggers []StringArgsCommandLogger
1718}
1819
19- func NewSuperStringArgsDispatcher (loggers ... StringArgsCommandLogger ) * SuperStringArgsDispatcher {
20+ func NewSuperStringArgsDispatcher (baseCommand string , loggers ... StringArgsCommandLogger ) * SuperStringArgsDispatcher {
2021 return & SuperStringArgsDispatcher {
21- sub : make (map [string ]* StringArgsDispatcher ),
22- loggers : loggers ,
22+ baseCommand : baseCommand ,
23+ sub : make (map [string ]* StringArgsDispatcher ),
24+ loggers : loggers ,
2325 }
2426}
2527
@@ -32,7 +34,7 @@ func (disp *SuperStringArgsDispatcher) AddSuperCommand(superCommand string) (sub
3234 if _ , exists := disp .sub [superCommand ]; exists {
3335 return nil , fmt .Errorf ("super command already added: '%s'" , superCommand )
3436 }
35- subDisp = NewStringArgsDispatcher (disp .loggers ... )
37+ subDisp = NewStringArgsDispatcher (disp .baseCommand , disp . loggers ... )
3638 disp .sub [superCommand ] = subDisp
3739 return subDisp , nil
3840}
@@ -160,33 +162,32 @@ func (disp *SuperStringArgsDispatcher) MustDispatchCombinedCommandAndArgs(ctx co
160162 return superCommand , command
161163}
162164
163- func (disp * SuperStringArgsDispatcher ) PrintCommands (appName string ) {
165+ func (disp * SuperStringArgsDispatcher ) PrintCommands () {
164166 type superCmd struct {
165167 super string
166168 cmd * stringArgsCommand
167169 }
168-
169- var list []superCmd
170+ var commands []superCmd
170171 for super , sub := range disp .sub {
171172 for _ , cmd := range sub .comm {
172- list = append (list , superCmd {super : super , cmd : cmd })
173+ commands = append (commands , superCmd {super : super , cmd : cmd })
173174 }
174175 }
175- sort .Slice (list , func (i , j int ) bool {
176- if list [i ].super == list [j ].super {
177- return list [i ].cmd .command < list [j ].cmd .command
176+ sort .Slice (commands , func (i , j int ) bool {
177+ if commands [i ].super == commands [j ].super {
178+ return commands [i ].cmd .command < commands [j ].cmd .command
178179 }
179- return list [i ].super < list [j ].super
180+ return commands [i ].super < commands [j ].super
180181 })
181182
182- for i := range list {
183- cmd := list [i ].cmd
184- command := list [i ].super
183+ for i := range commands {
184+ cmd := commands [i ].cmd
185+ command := commands [i ].super
185186 if cmd .command != DefaultCommand {
186187 command += " " + cmd .command
187188 }
188189
189- UsageColor .Printf (" %s %s %s\n " , appName , command , functionArgsString (cmd .commandFunc ))
190+ UsageColor .Printf (" %s %s %s\n " , disp . baseCommand , command , functionArgsString (cmd .commandFunc ))
190191 if cmd .description != "" {
191192 DescriptionColor .Printf (" %s\n " , cmd .description )
192193 }
@@ -206,10 +207,45 @@ func (disp *SuperStringArgsDispatcher) PrintCommands(appName string) {
206207 }
207208}
208209
209- func (disp * SuperStringArgsDispatcher ) PrintCommandsUsageIntro (appName string , output io.Writer ) {
210- if len (disp .sub ) > 0 {
211- fmt .Fprint (output , "Commands:\n " )
212- disp .PrintCommands (appName )
213- // fmt.Fprint(output, "Flags:\n")
210+ func (disp * SuperStringArgsDispatcher ) PrintCommandsUsageIntro () {
211+ if len (disp .sub ) == 0 {
212+ return
213+ }
214+ fmt .Println ("Commands:" )
215+ disp .PrintCommands ()
216+ }
217+
218+ func (disp * SuperStringArgsDispatcher ) PrintCompletion (args []string ) {
219+ prefix := ""
220+ if len (args ) > 0 {
221+ prefix = args [0 ]
222+ }
223+ type superCmd struct {
224+ super string
225+ cmd * stringArgsCommand
226+ }
227+ var commands []superCmd
228+ for super , sub := range disp .sub {
229+ for _ , cmd := range sub .comm {
230+ commands = append (commands , superCmd {super : super , cmd : cmd })
231+ }
232+ }
233+ sort .Slice (commands , func (i , j int ) bool {
234+ if commands [i ].super == commands [j ].super {
235+ return commands [i ].cmd .command < commands [j ].cmd .command
236+ }
237+ return commands [i ].super < commands [j ].super
238+ })
239+
240+ for i := range commands {
241+ cmd := commands [i ].cmd
242+ command := commands [i ].super
243+ if cmd .command != DefaultCommand {
244+ command += " " + cmd .command
245+ }
246+ // TODO subcommand completion
247+ if strings .HasPrefix (command , prefix ) {
248+ fmt .Println (disp .baseCommand , command )
249+ }
214250 }
215251}
0 commit comments