Skip to content

Commit c6c4e9c

Browse files
authored
Can specify the node path (#233)
1 parent a6367f5 commit c6c4e9c

File tree

5 files changed

+65
-27
lines changed

5 files changed

+65
-27
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/extension.ts

+1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>
4141
leetCodePreviewProvider,
4242
leetCodeResultProvider,
4343
leetCodeSolutionProvider,
44+
leetCodeExecutor,
4445
vscode.window.createTreeView("leetCodeExplorer", { treeDataProvider: leetCodeTreeDataProvider, showCollapseAll: true }),
4546
vscode.languages.registerCodeLensProvider({ scheme: "file" }, codeLensProvider),
4647
vscode.commands.registerCommand("leetcode.deleteCache", () => cache.deleteCache()),

src/leetCodeExecutor.ts

+51-21
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,29 @@ import * as cp from "child_process";
55
import * as fse from "fs-extra";
66
import * as path from "path";
77
import * as requireFromString from "require-from-string";
8-
import * as vscode from "vscode";
8+
import { ConfigurationChangeEvent, Disposable, MessageItem, window, workspace, WorkspaceConfiguration } from "vscode";
99
import { Endpoint, IProblem, supportedPlugins } from "./shared";
1010
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

15-
class LeetCodeExecutor {
16+
class LeetCodeExecutor implements Disposable {
1617
private leetCodeRootPath: string;
1718
private leetCodeRootPathInWsl: string;
19+
private nodeExecutable: string;
20+
private configurationChangeListener: Disposable;
1821

1922
constructor() {
2023
this.leetCodeRootPath = path.join(__dirname, "..", "..", "node_modules", "vsc-leetcode-cli");
2124
this.leetCodeRootPathInWsl = "";
25+
this.nodeExecutable = this.getNodePath();
26+
this.configurationChangeListener = workspace.onDidChangeConfiguration((event: ConfigurationChangeEvent) => {
27+
if (event.affectsConfiguration("leetcode.nodePath")) {
28+
this.nodeExecutable = this.getNodePath();
29+
}
30+
}, this);
2231
}
2332

2433
public async getLeetCodeRootPath(): Promise<string> { // not wrapped by ""
@@ -36,10 +45,18 @@ class LeetCodeExecutor {
3645
}
3746

3847
public async meetRequirements(): Promise<boolean> {
48+
if (this.nodeExecutable !== "node") {
49+
if (!await fse.pathExists(this.nodeExecutable)) {
50+
throw new Error(`The Node.js executable does not exist on path ${this.nodeExecutable}`);
51+
}
52+
if (useWsl()) {
53+
this.nodeExecutable = await toWslPath(this.nodeExecutable);
54+
}
55+
}
3956
try {
40-
await this.executeCommandEx("node", ["-v"]);
57+
await this.executeCommandEx(this.nodeExecutable, ["-v"]);
4158
} catch (error) {
42-
const choice: vscode.MessageItem | undefined = await vscode.window.showErrorMessage(
59+
const choice: MessageItem | undefined = await window.showErrorMessage(
4360
"LeetCode extension needs Node.js installed in environment path",
4461
DialogOptions.open,
4562
);
@@ -50,28 +67,28 @@ class LeetCodeExecutor {
5067
}
5168
for (const plugin of supportedPlugins) {
5269
try { // Check plugin
53-
await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "plugin", "-e", plugin]);
70+
await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "plugin", "-e", plugin]);
5471
} catch (error) { // Download plugin and activate
55-
await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "plugin", "-i", plugin]);
72+
await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "plugin", "-i", plugin]);
5673
}
5774
}
5875
return true;
5976
}
6077

6178
public async deleteCache(): Promise<string> {
62-
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "cache", "-d"]);
79+
return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "cache", "-d"]);
6380
}
6481

6582
public async getUserInfo(): Promise<string> {
66-
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "user"]);
83+
return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "user"]);
6784
}
6885

6986
public async signOut(): Promise<string> {
70-
return await await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "user", "-L"]);
87+
return await await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "user", "-L"]);
7188
}
7289

7390
public async listProblems(showLocked: boolean): Promise<string> {
74-
return await this.executeCommandEx("node", showLocked ?
91+
return await this.executeCommandEx(this.nodeExecutable, showLocked ?
7592
[await this.getLeetCodeBinaryPath(), "list"] :
7693
[await this.getLeetCodeBinaryPath(), "list", "-q", "L"],
7794
);
@@ -82,37 +99,37 @@ class LeetCodeExecutor {
8299
const filePath: string = path.join(outDir, fileName);
83100

84101
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]);
102+
const codeTemplate: string = await this.executeCommandWithProgressEx("Fetching problem data...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "show", problemNode.id, "-cx", "-l", language]);
86103
await fse.writeFile(filePath, codeTemplate);
87104
}
88105

89106
return filePath;
90107
}
91108

92109
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]);
110+
const solution: string = await this.executeCommandWithProgressEx("Fetching top voted solution from discussions...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "show", problemNode.id, "--solution", "-l", language]);
94111
return solution;
95112
}
96113

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

101118
public async listSessions(): Promise<string> {
102-
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "session"]);
119+
return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "session"]);
103120
}
104121

105122
public async enableSession(name: string): Promise<string> {
106-
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "session", "-e", name]);
123+
return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "session", "-e", name]);
107124
}
108125

109126
public async createSession(name: string): Promise<string> {
110-
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "session", "-c", name]);
127+
return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "session", "-c", name]);
111128
}
112129

113130
public async submitSolution(filePath: string): Promise<string> {
114131
try {
115-
return await this.executeCommandWithProgressEx("Submitting to LeetCode...", "node", [await this.getLeetCodeBinaryPath(), "submit", `"${filePath}"`]);
132+
return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "submit", `"${filePath}"`]);
116133
} catch (error) {
117134
if (error.result) {
118135
return error.result;
@@ -123,18 +140,18 @@ class LeetCodeExecutor {
123140

124141
public async testSolution(filePath: string, testString?: string): Promise<string> {
125142
if (testString) {
126-
return await this.executeCommandWithProgressEx("Submitting to LeetCode...", "node", [await this.getLeetCodeBinaryPath(), "test", `"${filePath}"`, "-t", `${testString}`]);
143+
return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "test", `"${filePath}"`, "-t", `${testString}`]);
127144
}
128-
return await this.executeCommandWithProgressEx("Submitting to LeetCode...", "node", [await this.getLeetCodeBinaryPath(), "test", `"${filePath}"`]);
145+
return await this.executeCommandWithProgressEx("Submitting to LeetCode...", this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "test", `"${filePath}"`]);
129146
}
130147

131148
public async switchEndpoint(endpoint: string): Promise<string> {
132149
switch (endpoint) {
133150
case Endpoint.LeetCodeCN:
134-
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "plugin", "-e", "leetcode.cn"]);
151+
return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "plugin", "-e", "leetcode.cn"]);
135152
case Endpoint.LeetCode:
136153
default:
137-
return await this.executeCommandEx("node", [await this.getLeetCodeBinaryPath(), "plugin", "-d", "leetcode.cn"]);
154+
return await this.executeCommandEx(this.nodeExecutable, [await this.getLeetCodeBinaryPath(), "plugin", "-d", "leetcode.cn"]);
138155
}
139156
}
140157

@@ -149,6 +166,19 @@ class LeetCodeExecutor {
149166
return { companies: COMPONIES, tags: TAGS };
150167
}
151168

169+
public get node(): string {
170+
return this.nodeExecutable;
171+
}
172+
173+
public dispose(): void {
174+
this.configurationChangeListener.dispose();
175+
}
176+
177+
private getNodePath(): string {
178+
const extensionConfig: WorkspaceConfiguration = workspace.getConfiguration("leetcode", null);
179+
return extensionConfig.get<string>("nodePath", "node" /* default value */);
180+
}
181+
152182
private async executeCommandEx(command: string, args: string[], options: cp.SpawnOptions = { shell: true }): Promise<string> {
153183
if (wsl.useWsl()) {
154184
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)