diff --git a/package.json b/package.json index b41bb759..81fbb217 100644 --- a/package.json +++ b/package.json @@ -201,6 +201,12 @@ "default": true, "scope": "window", "description": "Show a hint to set the default language." + }, + "leetcode.useWsl": { + "type": "boolean", + "default": false, + "scope": "window", + "description": "Use Node.js inside the Windows Subsystem for Linux." } } } diff --git a/src/commands/show.ts b/src/commands/show.ts index c42df84e..be8dcf7d 100644 --- a/src/commands/show.ts +++ b/src/commands/show.ts @@ -8,6 +8,7 @@ import { IQuickItemEx, languages, leetCodeBinaryPath, ProblemState } from "../sh import { executeCommand } from "../utils/cpUtils"; import { DialogOptions, DialogType, promptForOpenOutputChannel, promptForSignIn } from "../utils/uiUtils"; import { selectWorkspaceFolder } from "../utils/workspaceUtils"; +import * as wsl from "../utils/wslUtils"; import * as list from "./list"; export async function showProblem(channel: vscode.OutputChannel, node?: LeetCodeNode): Promise { @@ -53,7 +54,9 @@ async function showProblemInternal(channel: vscode.OutputChannel, id: string): P const reg: RegExp = /\* Source Code:\s*(.*)/; const match: RegExpMatchArray | null = result.match(reg); if (match && match.length >= 2) { - await vscode.window.showTextDocument(vscode.Uri.file(match[1].trim()), { preview: false }); + const filePath = wsl.useWsl() ? wsl.toWinPath(match[1].trim()) : match[1].trim(); + + await vscode.window.showTextDocument(vscode.Uri.file(filePath), { preview: false }); } else { throw new Error("Failed to fetch the problem information."); } diff --git a/src/leetCodeManager.ts b/src/leetCodeManager.ts index 313fe714..33c098b1 100644 --- a/src/leetCodeManager.ts +++ b/src/leetCodeManager.ts @@ -7,6 +7,7 @@ import { UserStatus } from "./shared"; import { leetCodeBinaryPath } from "./shared"; import { executeCommand } from "./utils/cpUtils"; import { DialogType, promptForOpenOutputChannel } from "./utils/uiUtils"; +import * as wsl from "./utils/wslUtils"; export interface ILeetCodeManager extends EventEmitter { getLoginStatus(channel: vscode.OutputChannel): void; @@ -43,7 +44,11 @@ class LeetCodeManager extends EventEmitter implements ILeetCodeManager { try { const userName: string | undefined = await new Promise(async (resolve: (res: string | undefined) => void, reject: (e: Error) => void): Promise => { let result: string = ""; - const childProc: cp.ChildProcess = cp.spawn("node", [leetCodeBinaryPath, "user", "-l"], { shell: true }); + + const childProc: cp.ChildProcess = wsl.useWsl() + ? cp.spawn("wsl", ["node", leetCodeBinaryPath, "user", "-l"], { shell: true }) + : cp.spawn("node", [leetCodeBinaryPath, "user", "-l"], { shell: true }); + childProc.stdout.on("data", (data: string | Buffer) => { data = data.toString(); result = result.concat(data); diff --git a/src/shared.ts b/src/shared.ts index e3eee105..d9c64f7b 100644 --- a/src/shared.ts +++ b/src/shared.ts @@ -2,8 +2,15 @@ import * as path from "path"; import * as vscode from "vscode"; +import * as wsl from "./utils/wslUtils"; -export const leetCodeBinaryPath: string = `"${path.join(__dirname, "..", "..", "node_modules", "leetcode-cli", "bin", "leetcode")}"`; +let binPath = path.join(__dirname, "..", "..", "node_modules", "leetcode-cli", "bin", "leetcode"); + +if (wsl.useWsl()) { + binPath = wsl.toWslPath(binPath); +} + +export const leetCodeBinaryPath: string = `"${binPath}"`; export interface IQuickItemEx extends vscode.QuickPickItem { value: T; diff --git a/src/utils/cpUtils.ts b/src/utils/cpUtils.ts index 8faddf05..a8f6fd9a 100644 --- a/src/utils/cpUtils.ts +++ b/src/utils/cpUtils.ts @@ -2,11 +2,15 @@ import * as cp from "child_process"; import * as vscode from "vscode"; +import * as wsl from "./wslUtils"; export async function executeCommand(channel: vscode.OutputChannel, command: string, args: string[], options: cp.SpawnOptions = { shell: true }): Promise { return new Promise((resolve: (res: string) => void, reject: (e: Error) => void): void => { let result: string = ""; - const childProc: cp.ChildProcess = cp.spawn(command, args, options); + + const childProc: cp.ChildProcess = wsl.useWsl() + ? cp.spawn("wsl", [command].concat(args), options) + : cp.spawn(command, args, options); childProc.stdout.on("data", (data: string | Buffer) => { data = data.toString(); diff --git a/src/utils/workspaceUtils.ts b/src/utils/workspaceUtils.ts index f8958a54..089282ff 100644 --- a/src/utils/workspaceUtils.ts +++ b/src/utils/workspaceUtils.ts @@ -3,6 +3,7 @@ import * as os from "os"; import * as path from "path"; import * as vscode from "vscode"; +import * as wsl from "./wslUtils"; export async function selectWorkspaceFolder(): Promise { let folder: vscode.WorkspaceFolder | undefined; @@ -15,7 +16,10 @@ export async function selectWorkspaceFolder(): Promise { folder = vscode.workspace.workspaceFolders[0]; } } - return folder ? folder.uri.fsPath : path.join(os.homedir(), ".leetcode"); + + const workFolder = folder ? folder.uri.fsPath : path.join(os.homedir(), ".leetcode"); + + return wsl.useWsl() ? wsl.toWslPath(workFolder) : workFolder; } export async function getActivefilePath(uri?: vscode.Uri): Promise { @@ -33,5 +37,5 @@ export async function getActivefilePath(uri?: vscode.Uri): Promise("useWsl") === true; +} + +export function toWslPath(path: string): string { + return cp.execFileSync("wsl", ["wslpath", "-u", `${path.replace(/\\/g, "/")}`]).toString().trim(); +} + +export function toWinPath(path: string): string { + return cp.execFileSync("wsl", ["wslpath", "-w", path]).toString().trim(); +}