Skip to content

Commit 1cdca10

Browse files
ringcrljdneo
authored andcommitted
Add a new config: 'outputFolder' to support generate file into a customized folder (LeetCode-OpenSource#123)
1 parent b15f4f8 commit 1cdca10

File tree

2 files changed

+54
-10
lines changed

2 files changed

+54
-10
lines changed

package.json

+5
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,11 @@
247247
"leetcode-cn"
248248
],
249249
"description": "Endpoint of the user account."
250+
},
251+
"leetcode.outputFolder": {
252+
"type": "string",
253+
"scope": "application",
254+
"description": "Specify the relative path to save the problem files."
250255
}
251256
}
252257
}

src/commands/show.ts

+49-10
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
// Licensed under the MIT license.
33

44
import * as fse from "fs-extra";
5+
import * as path from "path";
56
import * as vscode from "vscode";
67
import { LeetCodeNode } from "../explorer/LeetCodeNode";
8+
import { leetCodeChannel } from "../leetCodeChannel";
79
import { leetCodeExecutor } from "../leetCodeExecutor";
810
import { leetCodeManager } from "../leetCodeManager";
911
import { IProblem, IQuickItemEx, languages, ProblemState } from "../shared";
@@ -16,15 +18,15 @@ export async function showProblem(node?: LeetCodeNode): Promise<void> {
1618
if (!node) {
1719
return;
1820
}
19-
await showProblemInternal(node.id);
21+
await showProblemInternal(node);
2022
}
2123

2224
export async function searchProblem(): Promise<void> {
2325
if (!leetCodeManager.getUser()) {
2426
promptForSignIn();
2527
return;
2628
}
27-
const choice: IQuickItemEx<string> | undefined = await vscode.window.showQuickPick(
29+
const choice: IQuickItemEx<IProblem> | undefined = await vscode.window.showQuickPick(
2830
parseProblemsToPicks(list.listProblems()),
2931
{
3032
matchOnDetail: true,
@@ -37,7 +39,7 @@ export async function searchProblem(): Promise<void> {
3739
await showProblemInternal(choice.value);
3840
}
3941

40-
async function showProblemInternal(id: string): Promise<void> {
42+
async function showProblemInternal(node: IProblem): Promise<void> {
4143
try {
4244
const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode");
4345
let defaultLanguage: string | undefined = leetCodeConfig.get<string>("defaultLanguage");
@@ -49,9 +51,21 @@ async function showProblemInternal(id: string): Promise<void> {
4951
return;
5052
}
5153

52-
const outDir: string = await selectWorkspaceFolder();
54+
let outDir: string = await selectWorkspaceFolder();
55+
let relativePath: string = (leetCodeConfig.get<string>("outputFolder") || "").trim();
56+
const matchResult: RegExpMatchArray | null = relativePath.match(/\$\{(.*?)\}/);
57+
if (matchResult) {
58+
const resolvedPath: string | undefined = await resolveRelativePath(matchResult[1].toLocaleLowerCase(), node, language);
59+
if (!resolvedPath) {
60+
leetCodeChannel.appendLine("Showing problem canceled by user.");
61+
return;
62+
}
63+
relativePath = resolvedPath;
64+
}
65+
66+
outDir = path.join(outDir, relativePath);
5367
await fse.ensureDir(outDir);
54-
const result: string = await leetCodeExecutor.showProblem(id, language, outDir);
68+
const result: string = await leetCodeExecutor.showProblem(node.id, language, outDir);
5569
const reg: RegExp = /\* Source Code:\s*(.*)/;
5670
const match: RegExpMatchArray | null = result.match(reg);
5771
if (match && match.length >= 2) {
@@ -76,17 +90,17 @@ async function showProblemInternal(id: string): Promise<void> {
7690
}
7791
}
7892
} catch (error) {
79-
await promptForOpenOutputChannel("Failed to fetch the problem information. Please open the output channel for details.", DialogType.error);
93+
await promptForOpenOutputChannel("Failed to show the problem. Please open the output channel for details.", DialogType.error);
8094
}
8195
}
8296

83-
async function parseProblemsToPicks(p: Promise<IProblem[]>): Promise<Array<IQuickItemEx<string>>> {
84-
return new Promise(async (resolve: (res: Array<IQuickItemEx<string>>) => void): Promise<void> => {
85-
const picks: Array<IQuickItemEx<string>> = (await p).map((problem: IProblem) => Object.assign({}, {
97+
async function parseProblemsToPicks(p: Promise<IProblem[]>): Promise<Array<IQuickItemEx<IProblem>>> {
98+
return new Promise(async (resolve: (res: Array<IQuickItemEx<IProblem>>) => void): Promise<void> => {
99+
const picks: Array<IQuickItemEx<IProblem>> = (await p).map((problem: IProblem) => Object.assign({}, {
86100
label: `${parseProblemDecorator(problem.state, problem.locked)}${problem.id}.${problem.name}`,
87101
description: "",
88102
detail: `AC rate: ${problem.passRate}, Difficulty: ${problem.difficulty}`,
89-
value: problem.id,
103+
value: problem,
90104
}));
91105
resolve(picks);
92106
});
@@ -102,3 +116,28 @@ function parseProblemDecorator(state: ProblemState, locked: boolean): string {
102116
return locked ? "$(lock) " : "";
103117
}
104118
}
119+
120+
async function resolveRelativePath(value: string, node: IProblem, selectedLanguage: string): Promise<string | undefined> {
121+
switch (value) {
122+
case "tag":
123+
if (node.tags.length === 1) {
124+
return node.tags[0];
125+
}
126+
return await vscode.window.showQuickPick(
127+
node.tags,
128+
{
129+
matchOnDetail: true,
130+
placeHolder: "Multiple tags available, please select one",
131+
ignoreFocusOut: true,
132+
},
133+
);
134+
case "language":
135+
return selectedLanguage;
136+
case "difficulty":
137+
return node.difficulty;
138+
default:
139+
const errorMsg: string = `The config '${value}' is not supported.`;
140+
leetCodeChannel.appendLine(errorMsg);
141+
throw new Error(errorMsg);
142+
}
143+
}

0 commit comments

Comments
 (0)