22 spawnSync ,
33 type SpawnSyncOptionsWithStringEncoding ,
44} from 'child_process' ;
5+ import fs from 'node:fs' ;
56import path from 'node:path' ;
67import { RootCommand } from '../src/t.js' ;
78
@@ -27,14 +28,15 @@ function runCompletionCommand(
2728 leadingArgs : string [ ] ,
2829 completionArgs : string [ ]
2930) : string {
31+ const targetCommand = preferCmdShim ( command ) ;
3032 const args = [ ...leadingArgs , 'complete' , '--' , ...completionArgs ] ;
3133
3234 // PowerShell: prefer invoking via powershell.exe so .ps1 shims are resolved.
33- if ( isPowerShellEnv && path . extname ( command ) === '' ) {
34- return runCompletionViaPowerShell ( command , args ) ;
35+ if ( isPowerShellEnv && path . extname ( targetCommand ) === '' ) {
36+ return runCompletionViaPowerShell ( targetCommand , args ) ;
3537 }
3638
37- const result = spawnSync ( command , args , completionSpawnOptions ) ;
39+ const result = spawnSync ( targetCommand , args , completionSpawnOptions ) ;
3840
3941 return ( result . stdout ?? '' ) . trim ( ) ;
4042}
@@ -64,25 +66,6 @@ function runCompletionViaPowerShell(command: string, args: string[]): string {
6466 return ( psResult . stdout ?? '' ) . trim ( ) ;
6567}
6668
67- async function checkCliHasCompletions (
68- cliName : string ,
69- packageManager : string
70- ) : Promise < boolean > {
71- try {
72- const result = runCompletionCommand ( cliName , [ ] , [ ] ) ;
73- if ( result ) return true ;
74- } catch {
75- noop ( ) ;
76- }
77-
78- try {
79- const result = runCompletionCommand ( packageManager , [ cliName ] , [ ] ) ;
80- return ! ! result ;
81- } catch {
82- return false ;
83- }
84- }
85-
8669async function getCliCompletions (
8770 cliName : string ,
8871 packageManager : string ,
@@ -148,39 +131,46 @@ export class PackageManagerCompletion extends RootCommand {
148131 const knownCommands = [ ...this . commands . keys ( ) ] ;
149132
150133 if ( ! knownCommands . includes ( potentialCliName ) ) {
151- const hasCompletions = await checkCliHasCompletions (
134+ const cliArgs = normalizedArgs . slice ( 1 ) ;
135+ const suggestions = await getCliCompletions (
152136 potentialCliName ,
153- this . packageManager
137+ this . packageManager ,
138+ cliArgs
154139 ) ;
155140
156- if ( hasCompletions ) {
157- const cliArgs = normalizedArgs . slice ( 1 ) ;
158- const suggestions = await getCliCompletions (
159- potentialCliName ,
160- this . packageManager ,
161- cliArgs
141+ if ( suggestions . length > 0 ) {
142+ debugLog (
143+ `Returning ${ suggestions . length } completions for ${ potentialCliName } `
162144 ) ;
163-
164- if ( suggestions . length > 0 ) {
165- debugLog (
166- `Returning ${ suggestions . length } completions for ${ potentialCliName } `
167- ) ;
168- for ( const suggestion of suggestions ) {
169- if ( suggestion . startsWith ( ':' ) ) continue ;
170- if ( suggestion . includes ( '\t' ) ) {
171- const [ value , description ] = suggestion . split ( '\t' ) ;
172- console . log ( `${ value } \t${ description } ` ) ;
173- } else {
174- console . log ( suggestion ) ;
175- }
145+ for ( const suggestion of suggestions ) {
146+ if ( suggestion . startsWith ( ':' ) ) continue ;
147+ if ( suggestion . includes ( '\t' ) ) {
148+ const [ value , description ] = suggestion . split ( '\t' ) ;
149+ console . log ( `${ value } \t${ description } ` ) ;
150+ } else {
151+ console . log ( suggestion ) ;
176152 }
177- console . log ( ':4' ) ;
178- return ;
179153 }
154+ console . log ( ':4' ) ;
155+ return ;
180156 }
181157 }
182158 }
183159
184160 return super . parse ( args ) ;
185161 }
186162}
163+
164+ function preferCmdShim ( command : string ) : string {
165+ if ( process . platform !== 'win32' ) return command ;
166+ if ( path . extname ( command ) !== '' ) return command ;
167+
168+ const pathEntries = ( process . env . PATH || '' ) . split ( path . delimiter ) ;
169+ for ( const entry of pathEntries ) {
170+ const candidate = path . join ( entry , `${ command } .cmd` ) ;
171+ if ( fs . existsSync ( candidate ) ) {
172+ return `${ command } .cmd` ;
173+ }
174+ }
175+ return command ;
176+ }
0 commit comments