Skip to content

Commit 7ca9b8a

Browse files
poppinlpjdneo
authored andcommitted
feat: support load code from local file for issue 59 (#149)
1 parent b781eef commit 7ca9b8a

File tree

7 files changed

+484
-1180
lines changed

7 files changed

+484
-1180
lines changed

package-lock.json

+433-1,167
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@
267267
},
268268
"devDependencies": {
269269
"@types/fs-extra": "5.0.0",
270+
"@types/lodash.kebabcase": "^4.1.5",
270271
"@types/mocha": "^2.2.42",
271272
"@types/node": "^7.0.43",
272273
"@types/require-from-string": "^1.2.0",
@@ -277,6 +278,7 @@
277278
"dependencies": {
278279
"fs-extra": "^6.0.1",
279280
"leetcode-cli": "2.6.1",
281+
"lodash.kebabcase": "^4.1.1",
280282
"require-from-string": "^2.0.2"
281283
}
282284
}

src/commands/show.ts

+3-9
Original file line numberDiff line numberDiff line change
@@ -65,16 +65,10 @@ async function showProblemInternal(node: IProblem): Promise<void> {
6565

6666
outDir = path.join(outDir, relativePath);
6767
await fse.ensureDir(outDir);
68-
const result: string = await leetCodeExecutor.showProblem(node.id, language, outDir);
69-
const reg: RegExp = /\* Source Code:\s*(.*)/;
70-
const match: RegExpMatchArray | null = result.match(reg);
71-
if (match && match.length >= 2) {
72-
const filePath: string = wsl.useWsl() ? await wsl.toWinPath(match[1].trim()) : match[1].trim();
7368

74-
await vscode.window.showTextDocument(vscode.Uri.file(filePath), { preview: false });
75-
} else {
76-
throw new Error("Failed to fetch the problem information.");
77-
}
69+
const originFilePath: string = await leetCodeExecutor.showProblem(node, language, outDir);
70+
const filePath: string = wsl.useWsl() ? await wsl.toWinPath(originFilePath) : originFilePath;
71+
await vscode.window.showTextDocument(vscode.Uri.file(filePath), { preview: false });
7872

7973
if (!defaultLanguage && leetCodeConfig.get<boolean>("showSetDefaultLanguageHint")) {
8074
const choice: vscode.MessageItem | undefined = await vscode.window.showInformationMessage(

src/leetCodeExecutor.ts

+12-3
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ import * as fse from "fs-extra";
66
import * as path from "path";
77
import * as requireFromString from "require-from-string";
88
import * as vscode from "vscode";
9-
import { Endpoint } from "./shared";
9+
import { Endpoint, IProblem } from "./shared";
1010
import { executeCommand, executeCommandWithProgress } from "./utils/cpUtils";
11+
import { genFileName } from "./utils/problemUtils";
1112
import { DialogOptions, openUrl } from "./utils/uiUtils";
1213
import * as wsl from "./utils/wslUtils";
1314

@@ -74,8 +75,16 @@ class LeetCodeExecutor {
7475
);
7576
}
7677

77-
public async showProblem(id: string, language: string, outDir: string): Promise<string> {
78-
return await this.executeCommandWithProgressEx("Fetching problem data...", "node", [await this.getLeetCodeBinaryPath(), "show", id, "-gx", "-l", language, "-o", `"${outDir}"`]);
78+
public async showProblem(node: IProblem, language: string, outDir: string): Promise<string> {
79+
const fileName: string = genFileName(node, language);
80+
const filePath: string = path.join(outDir, fileName);
81+
82+
if (!await fse.pathExists(filePath)) {
83+
const codeTemplate: string = await this.executeCommandWithProgressEx("Fetching problem data...", "node", [await this.getLeetCodeBinaryPath(), "show", node.id, "-cx", "-l", language]);
84+
await fse.writeFile(filePath, codeTemplate);
85+
}
86+
87+
return filePath;
7988
}
8089

8190
public async listSessions(): Promise<string> {

src/shared.ts

+17
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,23 @@ export const languages: string[] = [
2929
"swift",
3030
];
3131

32+
export const langExt: Map<string, string> = new Map([
33+
["bash", "sh"],
34+
["c", "c"],
35+
["cpp", "cpp"],
36+
["csharp", "cs"],
37+
["golang", "go"],
38+
["java", "java"],
39+
["javascript", "js"],
40+
["kotlin", "kt"],
41+
["mysql", "sql"],
42+
["python", "py"],
43+
["python3", "py"],
44+
["ruby", "rb"],
45+
["scala", "scala"],
46+
["swift", "swift"],
47+
]);
48+
3249
export enum ProblemState {
3350
AC = 1,
3451
NotAC = 2,

src/utils/osUtils.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export function isWindows(): boolean {
66
}
77

88
export function usingCmd(): boolean {
9-
const comSpec: string = process.env.ComSpec;
9+
const comSpec: string | undefined = process.env.ComSpec;
1010
// 'cmd.exe' is used as a fallback if process.env.ComSpec is unavailable.
1111
if (!comSpec) {
1212
return true;

src/utils/problemUtils.ts

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import kebabCase = require("lodash.kebabcase");
2+
import { IProblem, langExt } from "../shared";
3+
4+
export function genFileExt(language: string): string {
5+
const ext: string | undefined = langExt.get(language);
6+
if (!ext) {
7+
throw new Error(`The language "${language}" is not supported.`);
8+
}
9+
return ext;
10+
}
11+
12+
export function genFileName(node: IProblem, language: string): string {
13+
const slug: string = kebabCase(node.name);
14+
const ext: string = genFileExt(language);
15+
return `${node.id}.${slug}.${ext}`;
16+
}

0 commit comments

Comments
 (0)