@@ -80,6 +80,7 @@ type Option = {
8080type Command = {
8181 name : string ;
8282 description : string ;
83+ args : boolean [ ]
8384 handler : Handler ;
8485 options : Map < string , Option > ;
8586 parent ?: Command ;
@@ -101,6 +102,7 @@ export class Completion {
101102 this . commands . set ( key , {
102103 name : key ,
103104 description,
105+ args,
104106 handler,
105107 options : new Map ( ) ,
106108 parent : parent ? this . commands . get ( parent ) ! : undefined ,
@@ -137,11 +139,10 @@ export class Completion {
137139 let toComplete = args [ args . length - 1 ] || '' ;
138140 const previousArgs = args . slice ( 0 , - 1 ) ;
139141
140- if ( previousArgs . length > 0 ) {
141- const lastPrevArg = previousArgs [ previousArgs . length - 1 ] ;
142- if ( lastPrevArg . startsWith ( '--' ) && ! endsWithSpace ) {
143- const { handler } = matchedCommand . options . get ( lastPrevArg ) ! ;
144- if ( handler ) {
142+ const lastPrevArg = previousArgs [ previousArgs . length - 1 ] ;
143+ if ( lastPrevArg ?. startsWith ( '--' ) && ! endsWithSpace ) {
144+ const { handler } = matchedCommand . options . get ( lastPrevArg ) ! ;
145+ if ( handler ) {
145146 const flagSuggestions = await handler (
146147 previousArgs ,
147148 toComplete ,
@@ -153,11 +154,7 @@ export class Completion {
153154 )
154155 ) ;
155156 directive = ShellCompDirective . ShellCompDirectiveNoFileComp ;
156- // completions.forEach((comp) => );
157- // console.log(`:${directive}`);
158- // return;
159157 }
160- }
161158 } else if ( toComplete . startsWith ( '--' ) ) {
162159 directive = ShellCompDirective . ShellCompDirectiveNoFileComp ;
163160 const equalsIndex = toComplete . indexOf ( '=' ) ;
@@ -215,13 +212,15 @@ export class Completion {
215212 }
216213 } else {
217214 const potentialCommandParts = potentialCommand . split ( ' ' ) ;
215+ console . log ( potentialCommandParts )
218216 for ( const [ k , v ] of this . commands ) {
219217 // if the command is root, skip it
220218 if ( k === '' ) {
221219 continue ;
222220 }
223221
224- const parts = k . split ( ' ' ) ;
222+ const parts = [ ...k . split ( ' ' ) , ...v . args ] ;
223+ console . log ( parts )
225224 for ( let i = 0 ; i < parts . length ; i ++ ) {
226225 const part = parts [ i ] ;
227226 const potentialPart = potentialCommandParts [ i ] || '' ;
@@ -233,13 +232,35 @@ export class Completion {
233232 break ;
234233 }
235234
235+ async function callHandler ( ) {
236+ console . log ( matchedCommand )
237+ console . log ( 'callHandler' , previousArgs , toComplete , endsWithSpace )
238+ completions . push ( ...await matchedCommand . handler ?.(
239+ previousArgs ,
240+ toComplete ,
241+ endsWithSpace
242+ ) )
243+ }
244+
236245 // If we're at the current word being completed
237246 if ( i === potentialCommandParts . length - 1 ) {
238- // Only add if it matches the current partial input
239- if ( part . startsWith ( potentialPart ) ) {
240- completions . push ( { value : part , description : v . description } ) ;
247+ if ( endsWithSpace ) {
248+ const nextPart = parts [ i + 1 ]
249+ if ( typeof nextPart === 'boolean' ) {
250+ await callHandler ( )
251+ }
252+ } else {
253+ // Only add if it matches the current partial input
254+ console . log ( 'part' , part , potentialPart )
255+ if ( typeof part === 'boolean' ) {
256+ await callHandler ( )
257+ } else if ( part . startsWith ( potentialPart ) ) {
258+ completions . push ( { value : part , description : v . description } ) ;
259+ }
241260 }
242261 break ;
262+ } else if ( i === parts . length - 1 && part === true ) { // variadic
263+ await callHandler ( )
243264 }
244265
245266 // For previous parts, they must match exactly
0 commit comments