@@ -2,13 +2,55 @@ import type { ParentPort } from '../types'
22import { Unport } from 'unport'
33import { workspace } from 'vscode'
44import type { ChildProcessWithoutNullStreams } from 'node:child_process'
5+ import { execFile } from 'node:child_process'
56
6- const defaultBinary = process . platform === 'win32' ? 'ast-grep.exe' : 'ast-grep'
7+ let defaultBinary : string
8+
9+ export async function detectDefaultBinaryAtStart ( ) {
10+ if ( defaultBinary ) {
11+ return
12+ }
13+ if ( process . platform !== 'win32' ) {
14+ defaultBinary = 'ast-grep'
15+ return
16+ }
17+ // on windows, binary command is confusing like sh*t
18+ // different installation method and different shell will
19+ // resolve totally different binary
20+ // See:
21+ // https://zenn.dev/hd_nvim/articles/e49ef2c812ae8d#comment-0b861171ac40cb
22+ // https://github.com/ast-grep/ast-grep-vscode/issues/235
23+ // https://github.com/nodejs/node/issues/29532#issue-492569087
24+ for ( const cmd of [ 'ast-grep' , 'ast-grep.exe' , 'ast-grep.cmd' ] ) {
25+ if ( await testBinaryExist ( cmd ) ) {
26+ defaultBinary = cmd
27+ return
28+ }
29+ }
30+ // every possible command tried, fallback to ast-grep
31+ defaultBinary = 'ast-grep'
32+ }
733
834export function resolveBinary ( ) {
935 return workspace . getConfiguration ( 'astGrep' ) . get ( 'serverPath' , defaultBinary )
1036}
1137
38+ export async function testBinaryExist ( command : string ) {
39+ return new Promise ( r => {
40+ execFile (
41+ command ,
42+ [ '-h' ] ,
43+ {
44+ // for windows
45+ shell : process . platform === 'win32' ,
46+ } ,
47+ err => {
48+ r ( ! err )
49+ } ,
50+ )
51+ } )
52+ }
53+
1254export const parentPort : ParentPort = new Unport ( )
1355
1456export function streamedPromise < T > (
0 commit comments