@@ -85,9 +85,14 @@ export class Completion {
8585 commands = new Map < string , Command > ( ) ;
8686
8787 addCommand ( name : string , description : string , handler : Handler , parent ?: string ) {
88- const key = parent ? `${ parent } ${ name } ` : name
89- this . commands . set ( key , { description, handler, options : new Map ( ) , parent : parent ? this . commands . get ( parent ) ! : this . commands . get ( '' ) ! } ) ;
90- return key
88+ const key = parent ? `${ parent } ${ name } ` : name ;
89+ this . commands . set ( key , {
90+ description,
91+ handler,
92+ options : new Map ( ) ,
93+ parent : parent ? this . commands . get ( parent ) ! : undefined ,
94+ } ) ;
95+ return key ;
9196 }
9297
9398 addOption ( command : string , option : string , description : string , handler : Handler ) {
@@ -96,7 +101,7 @@ export class Completion {
96101 throw new Error ( `Command ${ command } not found.` ) ;
97102 }
98103 cmd . options . set ( option , { description, handler } ) ;
99- return option
104+ return option ;
100105 }
101106
102107 async parse ( args : string [ ] , potentialCommand : string ) {
@@ -119,12 +124,12 @@ export class Completion {
119124 if ( handler ) {
120125 const flagSuggestions = await handler ( previousArgs , toComplete , endsWithSpace ) ;
121126 completions . push (
122- ...flagSuggestions . filter ( comp => comp . value . startsWith ( toComplete ) ) . map (
123- ( comp ) => ` ${ comp . value } \t ${ comp . description ?? "" } `
124- )
127+ ...flagSuggestions
128+ . filter ( comp => comp . value . startsWith ( toComplete ) )
129+ . map ( comp => ` ${ comp . value } \t ${ comp . description ?? "" } ` )
125130 ) ;
126131 directive = ShellCompDirective . ShellCompDirectiveNoFileComp ;
127- completions . forEach ( ( comp ) => console . log ( comp ) ) ;
132+ completions . forEach ( comp => console . log ( comp ) ) ;
128133 console . log ( `:${ directive } ` ) ;
129134 return ;
130135 }
@@ -143,7 +148,7 @@ export class Completion {
143148 if ( handler ) {
144149 const suggestions = await handler ( previousArgs , valueToComplete , endsWithSpace ) ;
145150 completions . push ( ...suggestions . map (
146- ( comp ) => `${ comp . value } \t${ comp . description ?? "" } `
151+ comp => `${ comp . value } \t${ comp . description ?? "" } `
147152 ) ) ;
148153 }
149154 } else if ( ! endsWithSpace ) {
@@ -168,7 +173,7 @@ export class Completion {
168173
169174 completions . push (
170175 ...availableFlags . map (
171- ( flag ) => `${ flag } \t${ options . get ( flag ) ! . description ?? "" } `
176+ flag => `${ flag } \t${ options . get ( flag ) ! . description ?? "" } `
172177 )
173178 ) ;
174179 } else {
@@ -177,33 +182,27 @@ export class Completion {
177182 if ( handler ) {
178183 const suggestions = await handler ( previousArgs , toComplete , endsWithSpace ) ;
179184 completions . push ( ...suggestions . map (
180- ( comp ) => `${ comp . value } \t${ comp . description ?? "" } `
185+ comp => `${ comp . value } \t${ comp . description ?? "" } `
181186 ) ) ;
182187 }
183-
184188 }
185- } else if ( ! toComplete && endsWithSpace ) {
186- directive = ShellCompDirective . ShellCompDirectiveNoFileComp ;
189+ } else {
190+ const availableSubcommands = [ ...this . commands . keys ( ) ]
191+ . filter ( cmd => cmd . startsWith ( potentialCommand ) && cmd !== potentialCommand )
192+ . map ( cmd => cmd . replace ( `${ potentialCommand } ` , "" ) . split ( " " ) [ 0 ] )
193+ . filter ( ( subcmd , index , self ) => self . indexOf ( subcmd ) === index ) // Remove duplicates
194+ . filter ( subcmd => subcmd . startsWith ( toComplete ) ) ;
187195
188196 completions . push (
189- ...Object . keys ( this . commands )
190- . filter ( ( cmd ) => cmd !== "complete" )
191- . map ( ( cmd ) => ` ${ cmd } \t ${ this . commands [ cmd ] . description } ` )
197+ ...availableSubcommands . map (
198+ subcmd => ` ${ subcmd } \t ${ this . commands . get ( ` ${ potentialCommand } ${ subcmd } ` ) ?. description ?? "" } `
199+ )
192200 ) ;
193201
194- const positionalCompletions = positionalMap . get ( potentialCommand ) || [ ] ;
195- for ( const positional of positionalCompletions ) {
196- const suggestions = await positional . completion ( previousArgs , "" ) ;
197- completions . push (
198- ...suggestions . map ( ( comp ) => `${ comp . action } \t${ comp . description ?? "" } ` )
199- ) ;
200- if ( suggestions . length > 0 ) {
201- directive = ShellCompDirective . ShellCompDirectiveNoFileComp ;
202- }
203- }
202+ directive = ShellCompDirective . ShellCompDirectiveNoFileComp ;
204203 }
205204
206- completions . forEach ( ( comp ) => console . log ( comp ) ) ;
205+ completions . forEach ( comp => console . log ( comp ) ) ;
207206 console . log ( `:${ directive } ` ) ;
208207 }
209208}
0 commit comments