Skip to content

Commit 69876ed

Browse files
fix: more binary detection for windows
related to #235
1 parent 58b4eeb commit 69876ed

File tree

4 files changed

+54
-25
lines changed

4 files changed

+54
-25
lines changed

src/extension/common.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,55 @@ import type { ParentPort } from '../types'
22
import { Unport } from 'unport'
33
import { workspace } from 'vscode'
44
import 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

834
export 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+
1254
export const parentPort: ParentPort = new Unport()
1355

1456
export function streamedPromise<T>(

src/extension/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import type { ExtensionContext } from 'vscode'
2+
import { detectDefaultBinaryAtStart } from './common'
23
import { activatePreview } from './preview'
34
import { activateWebview } from './webview'
45
import { activateLsp } from './lsp'
56
import { activateSearch } from './search'
67

7-
export function activate(context: ExtensionContext) {
8+
export async function activate(context: ExtensionContext) {
9+
await detectDefaultBinaryAtStart()
810
activateLsp(context)
911
activateWebview(context)
1012
activateSearch(context)

src/extension/lsp.ts

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import {
55
type ServerOptions,
66
type Executable,
77
} from 'vscode-languageclient/node'
8-
import { resolveBinary } from './common'
9-
import { execFile } from 'node:child_process'
8+
import { resolveBinary, testBinaryExist } from './common'
109

1110
let client: LanguageClient
1211
const diagnosticCollectionName = 'ast-grep-diagnostics'
@@ -25,28 +24,11 @@ function getExecutable(isDebug: boolean): Executable {
2524
...(isDebug ? { RUST_LOG: 'debug' } : {}),
2625
},
2726
// shell is required for Windows cmd to pick up global npm binary
28-
shell: true,
27+
shell: process.platform === 'win32',
2928
},
3029
}
3130
}
3231

33-
async function testBinaryExist() {
34-
const command = resolveBinary()
35-
return new Promise(r => {
36-
execFile(
37-
command,
38-
['-h'],
39-
{
40-
// for windows
41-
shell: true,
42-
},
43-
err => {
44-
r(!err)
45-
},
46-
)
47-
})
48-
}
49-
5032
async function fileExists(pathFromRoot: string): Promise<boolean> {
5133
const workspaceFolders = workspace.workspaceFolders
5234
if (!workspaceFolders) {
@@ -82,7 +64,7 @@ export async function activateLsp(context: ExtensionContext) {
8264
}),
8365
)
8466

85-
if (!(await testBinaryExist())) {
67+
if (!(await testBinaryExist(resolveBinary()))) {
8668
window
8769
.showErrorMessage(
8870
'ast-grep cannot be started. Make sure it is installed.',
@@ -124,7 +106,10 @@ export async function activateLsp(context: ExtensionContext) {
124106
)
125107

126108
// Automatically start the client only if we can find a config file
127-
if (await fileExists('sgconfig.yml')) {
109+
if (
110+
(await fileExists('sgconfig.yml')) ||
111+
(await fileExists('sgconfig.yaml'))
112+
) {
128113
// Start the client. This will also launch the server
129114
client.start()
130115
}

src/extension/search.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ export function buildCommand(query: CommandArgs) {
128128
// TODO: multi-workspaces support
129129
return spawn(command, args, {
130130
cwd: uris[0],
131-
// shell: true, // it is safe because it is end user input
131+
shell: process.platform === 'win32', // it is safe because it is end user input
132132
})
133133
}
134134

0 commit comments

Comments
 (0)