Skip to content

Commit 04ad29a

Browse files
committed
Can specify the node path
1 parent bcafa92 commit 04ad29a

File tree

4 files changed

+51
-24
lines changed

4 files changed

+51
-24
lines changed

package.json

+9-3
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@
271271
"type": "boolean",
272272
"default": false,
273273
"scope": "application",
274-
"description": "Use Node.js inside the Windows Subsystem for Linux."
274+
"description": "Use the Windows Subsystem for Linux."
275275
},
276276
"leetcode.endpoint": {
277277
"type": "string",
@@ -286,13 +286,19 @@
286286
"leetcode.outputFolder": {
287287
"type": "string",
288288
"scope": "application",
289-
"description": "Specify the relative path to save the problem files."
289+
"description": "The relative path to save the problem files."
290290
},
291291
"leetcode.enableStatusBar": {
292292
"type": "boolean",
293293
"default": true,
294294
"scope": "application",
295-
"description": "Specify whether the LeetCode status bar will be shown or not."
295+
"description": "Show the LeetCode status bar or not."
296+
},
297+
"leetcode.nodePath": {
298+
"type": "string",
299+
"default": "node",
300+
"scope": "application",
301+
"description": "The Node.js executable path."
296302
}
297303
}
298304
}

src/leetCodeExecutor.ts

+38-18
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,17 @@ import { executeCommand, executeCommandWithProgress } from "./utils/cpUtils";
1111
import { genFileName } from "./utils/problemUtils";
1212
import { DialogOptions, openUrl } from "./utils/uiUtils";
1313
import * as wsl from "./utils/wslUtils";
14+
import { toWslPath, useWsl } from "./utils/wslUtils";
1415

1516
class LeetCodeExecutor {
1617
private leetCodeRootPath: string;
1718
private leetCodeRootPathInWsl: string;
19+
private nodeExecutable: string;
1820

1921
constructor() {
2022
this.leetCodeRootPath = path.join(__dirname, "..", "..", "node_modules", "vsc-leetcode-cli");
2123
this.leetCodeRootPathInWsl = "";
24+
this.nodeExecutable = this.getNodePath();
2225
}
2326

2427
public async getLeetCodeRootPath(): Promise<string> { // not wrapped by ""
@@ -36,8 +39,16 @@ class LeetCodeExecutor {
3639
}
3740

3841
public async meetRequirements(): Promise<boolean> {
42+
if (this.nodeExecutable !== "node") {
43+
if (!await fse.pathExists(this.nodeExecutable)) {
44+
throw new Error(`The Node.js executable does not exist on path ${this.nodeExecutable}`);
45+
}
46+
if (useWsl()) {
47+
this.nodeExecutable = await toWslPath(this.nodeExecutable);
48+
}
49+
}
3950
try {
40-
await this.executeCommandEx("node", ["-v"]);
51+
await this.executeCommandEx(this.nodeExecutable, ["-v"]);
4152
} catch (error) {
4253
const choice: vscode.MessageItem | undefined = await vscode.window.showErrorMessage(
4354
"LeetCode extension needs Node.js installed in environment path",
@@ -50,28 +61,28 @@ class LeetCodeExecutor {
5061
}
5162
for (const plugin of supportedPlugins) {
5263
try { // Check plugin
53-
await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "plugin", "-e", plugin]);
64+
await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "plugin", "-e", plugin]);
5465
} catch (error) { // Download plugin and activate
55-
await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "plugin", "-i", plugin]);
66+
await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "plugin", "-i", plugin]);
5667
}
5768
}
5869
return true;
5970
}
6071

6172
public async deleteCache(): Promise<string> {
62-
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "cache", "-d"]);
73+
return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "cache", "-d"]);
6374
}
6475

6576
public async getUserInfo(): Promise<string> {
66-
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "user"]);
77+
return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "user"]);
6778
}
6879

6980
public async signOut(): Promise<string> {
70-
return await await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "user", "-L"]);
81+
return await await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "user", "-L"]);
7182
}
7283

7384
public async listProblems(showLocked: boolean): Promise<string> {
74-
return await this.executeCommandEx("node", showLocked ?
85+
return await this.executeCommandEx(this.nodeExecutable, showLocked ?
7586
[await this.getLeetCodeBinaryPath(), "list"] :
7687
[await this.getLeetCodeBinaryPath(), "list", "-q", "L"],
7788
);
@@ -82,52 +93,52 @@ class LeetCodeExecutor {
8293
const filePath: string = path.join(outDir, fileName);
8394

8495
if (!await fse.pathExists(filePath)) {
85-
const codeTemplate: string = await this.executeCommandWithProgressEx("Fetching problem data...", "node", [await this.getLeetCodeBinaryPath(), "show", problemNode.id, "-cx", "-l", language]);
96+
const codeTemplate: string = await this.executeCommandWithProgressEx("Fetching problem data...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "show", problemNode.id, "-cx", "-l", language]);
8697
await fse.writeFile(filePath, codeTemplate);
8798
}
8899

89100
return filePath;
90101
}
91102

92103
public async showSolution(problemNode: IProblem, language: string): Promise<string> {
93-
const solution: string = await this.executeCommandWithProgressEx("Fetching top voted solution from discussions...", "node", [await this.getLeetCodeBinaryPath(), "show", problemNode.id, "--solution", "-l", language]);
104+
const solution: string = await this.executeCommandWithProgressEx("Fetching top voted solution from discussions...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "show", problemNode.id, "--solution", "-l", language]);
94105
return solution;
95106
}
96107

97108
public async getDescription(problemNode: IProblem): Promise<string> {
98-
return await this.executeCommandWithProgressEx("Fetching problem description...", "node", [await this.getLeetCodeBinaryPath(), "show", problemNode.id, "-x"]);
109+
return await this.executeCommandWithProgressEx("Fetching problem description...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "show", problemNode.id, "-x"]);
99110
}
100111

101112
public async listSessions(): Promise<string> {
102-
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "session"]);
113+
return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "session"]);
103114
}
104115

105116
public async enableSession(name: string): Promise<string> {
106-
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "session", "-e", name]);
117+
return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "session", "-e", name]);
107118
}
108119

109120
public async createSession(name: string): Promise<string> {
110-
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "session", "-c", name]);
121+
return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "session", "-c", name]);
111122
}
112123

113124
public async submitSolution(filePath: string): Promise<string> {
114-
return await this.executeCommandWithProgressEx("Submitting to LeetCode...", "node", [await this.getLeetCodeBinaryPath(), "submit", `"${filePath}"`]);
125+
return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "submit", `"${filePath}"`]);
115126
}
116127

117128
public async testSolution(filePath: string, testString?: string): Promise<string> {
118129
if (testString) {
119-
return await this.executeCommandWithProgressEx("Submitting to LeetCode...", "node", [await this.getLeetCodeBinaryPath(), "test", `"${filePath}"`, "-t", `${testString}`]);
130+
return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "test", `"${filePath}"`, "-t", `${testString}`]);
120131
}
121-
return await this.executeCommandWithProgressEx("Submitting to LeetCode...", "node", [await this.getLeetCodeBinaryPath(), "test", `"${filePath}"`]);
132+
return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "test", `"${filePath}"`]);
122133
}
123134

124135
public async switchEndpoint(endpoint: string): Promise<string> {
125136
switch (endpoint) {
126137
case Endpoint.LeetCodeCN:
127-
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "plugin", "-e", "leetcode.cn"]);
138+
return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "plugin", "-e", "leetcode.cn"]);
128139
case Endpoint.LeetCode:
129140
default:
130-
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "plugin", "-d", "leetcode.cn"]);
141+
return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "plugin", "-d", "leetcode.cn"]);
131142
}
132143
}
133144

@@ -142,6 +153,15 @@ class LeetCodeExecutor {
142153
return { companies: COMPONIES, tags: TAGS };
143154
}
144155

156+
public get node(): string {
157+
return this.nodeExecutable;
158+
}
159+
160+
private getNodePath(): string {
161+
const extensionConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode", null);
162+
return extensionConfig.get<string>("nodePath", "node" /* default value */);
163+
}
164+
145165
private async executeCommandEx(command: string, args: string[], options: cp.SpawnOptions = { shell: true }): Promise<string> {
146166
if (wsl.useWsl()) {
147167
return await executeCommand("wsl", [command].concat(args), options);

src/leetCodeManager.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ class LeetCodeManager extends EventEmitter {
4242
const leetCodeBinaryPath: string = await leetCodeExecutor.getLeetCodeBinaryPath();
4343

4444
const childProc: cp.ChildProcess = wsl.useWsl()
45-
? cp.spawn("wsl", ["node", leetCodeBinaryPath, "user", "-l"], { shell: true })
46-
: cp.spawn("node", [leetCodeBinaryPath, "user", "-l"], {
45+
? cp.spawn("wsl", [leetCodeExecutor.node, leetCodeBinaryPath, "user", "-l"], { shell: true })
46+
: cp.spawn(leetCodeExecutor.node, [leetCodeBinaryPath, "user", "-l"], {
4747
shell: true,
4848
env: createEnvOption(),
4949
});

src/utils/wslUtils.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33

44
import * as vscode from "vscode";
55
import { executeCommand } from "./cpUtils";
6+
import { isWindows } from "./osUtils";
67

78
export function useWsl(): boolean {
89
const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode");
9-
return process.platform === "win32" && leetCodeConfig.get<boolean>("useWsl") === true;
10+
return isWindows() && leetCodeConfig.get<boolean>("useWsl") === true;
1011
}
1112

1213
export async function toWslPath(path: string): Promise<string> {

0 commit comments

Comments
 (0)