From b8b91a6a0d8fa1c8a1cbbfc2bdc66573f562c1c7 Mon Sep 17 00:00:00 2001 From: chengruilin Date: Tue, 12 Feb 2019 22:22:40 +0800 Subject: [PATCH 01/11] =?UTF-8?q?feat:=20=E4=B8=8B=E8=BD=BD=E9=A2=98?= =?UTF-8?q?=E7=9B=AE=E7=9A=84=E6=97=B6=E5=80=99=E6=A0=B9=E6=8D=AE=20tag=20?= =?UTF-8?q?=E8=BF=9B=E8=A1=8C=E5=88=86=E7=B1=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 17 +++++++++-------- docs/README_zh-CN.md | 17 +++++++++-------- package.json | 10 ++++++++++ src/commands/show.ts | 12 ++++++++---- src/extension.ts | 1 + 5 files changed, 37 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 438ab39a..e3ccab02 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,8 @@ Pick a Problem

-- Right click the problem in the `LeetCode Explorer` and select `Show Problem` will generate a new file with the problem description for you. +- Right click the problem in the `LeetCode Explorer` and select `Show problem` will generate a new file with the problem description for you. +- Right click the problem in the `LeetCode Explorer` and select `Show problem with tag` will generate a new file with the problem description and classified by tag folder. > Note: If no folder is opened in VS Code, the extension will save the problem files in **$HOME/.leetcode/**. @@ -114,13 +115,13 @@ ## Settings -| Setting Name | Description | Default Value | -|---|---|---| -| `leetcode.hideSolved` | Specify to hide the solved problems or not | `false` | -| `leetcode.showLocked` | Specify to show the locked problems or not. Only Premium users could open the locked problems | `false` | -| `leetcode.defaultLanguage` | Specify the default language used to solve the problem. Supported languages are: `bash`, `c`, `cpp`, `csharp`, `golang`, `java`, `javascript`, `kotlin`, `mysql`, `python`,`python3`,`ruby`,`scala`,`swift` | `N/A` | -| `leetcode.useWsl` | Specify whether to use WSL or not | `false` | -| `leetcode.endpoint` | Specify the active endpoint. Supported endpoints are: `leetcode`, `leetcode-cn` | `leetcode` | +| Setting Name | Description | Default Value | +| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | +| `leetcode.hideSolved` | Specify to hide the solved problems or not | `false` | +| `leetcode.showLocked` | Specify to show the locked problems or not. Only Premium users could open the locked problems | `false` | +| `leetcode.defaultLanguage` | Specify the default language used to solve the problem. Supported languages are: `bash`, `c`, `cpp`, `csharp`, `golang`, `java`, `javascript`, `kotlin`, `mysql`, `python`,`python3`,`ruby`,`scala`,`swift` | `N/A` | +| `leetcode.useWsl` | Specify whether to use WSL or not | `false` | +| `leetcode.endpoint` | Specify the active endpoint. Supported endpoints are: `leetcode`, `leetcode-cn` | `leetcode` | ## Release Notes diff --git a/docs/README_zh-CN.md b/docs/README_zh-CN.md index c91f8860..200e669f 100644 --- a/docs/README_zh-CN.md +++ b/docs/README_zh-CN.md @@ -67,7 +67,8 @@ 选择题目

-- 在 `LeetCode Explorer` 中**右键**题目并选择 `Show Problem` 进行答题。 +- 在 `LeetCode Explorer` 中**右键**题目并选择 `Show problem` 进行答题。 +- 在 `LeetCode Explorer` 中**右键**题目并选择 `Show problem with tag`,题目会被放进分类好的文件夹,并进行答题。 > 注意:若当前 VS Code 没有已打开的文件夹,则生成的题目文件会存储于 **$HOME/.leetcode/** 目录下。 @@ -114,13 +115,13 @@ ## 插件配置项 -| 配置项名称 | 描述 | 默认值 | -|---|---|---| -| `leetcode.hideSolved` | 指定是否要隐藏已解决的问题 | `false` | -| `leetcode.showLocked` | 指定是否显示付费题目,只有付费账户才可以打开付费题目 | `false` | -| `leetcode.defaultLanguage` | 指定答题时使用的默认语言,可选语言有:`bash`, `c`, `cpp`, `csharp`, `golang`, `java`, `javascript`, `kotlin`, `mysql`, `python`,`python3`,`ruby`,`scala`,`swift` | `N/A` | -| `leetcode.useWsl` | 指定是否启用 WSL | `false` | -| `leetcode.endpoint` | 指定使用的终端,可用终端有:`leetcode`, `leetcode-cn` | `leetcode` | +| 配置项名称 | 描述 | 默认值 | +| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | +| `leetcode.hideSolved` | 指定是否要隐藏已解决的问题 | `false` | +| `leetcode.showLocked` | 指定是否显示付费题目,只有付费账户才可以打开付费题目 | `false` | +| `leetcode.defaultLanguage` | 指定答题时使用的默认语言,可选语言有:`bash`, `c`, `cpp`, `csharp`, `golang`, `java`, `javascript`, `kotlin`, `mysql`, `python`,`python3`,`ruby`,`scala`,`swift` | `N/A` | +| `leetcode.useWsl` | 指定是否启用 WSL | `false` | +| `leetcode.endpoint` | 指定使用的终端,可用终端有:`leetcode`, `leetcode-cn` | `leetcode` | ## 更新日志 diff --git a/package.json b/package.json index 53aa74f2..e8cdfb2b 100644 --- a/package.json +++ b/package.json @@ -93,6 +93,11 @@ "title": "Show Problem", "category": "LeetCode" }, + { + "command": "leetcode.showProblemWithTag", + "title": "Show problem with tag", + "category": "LeetCode" + }, { "command": "leetcode.searchProblem", "title": "Search Problem", @@ -158,6 +163,11 @@ "command": "leetcode.showProblem", "when": "view == leetCodeExplorer && viewItem == problem", "group": "leetcode@1" + }, + { + "command": "leetcode.showProblemWithTag", + "when": "view == leetCodeExplorer && viewItem == problem", + "group": "leetcode@1" } ], "commandPalette": [ diff --git a/src/commands/show.ts b/src/commands/show.ts index 780aa45e..a8ca82a6 100644 --- a/src/commands/show.ts +++ b/src/commands/show.ts @@ -12,11 +12,11 @@ import { selectWorkspaceFolder } from "../utils/workspaceUtils"; import * as wsl from "../utils/wslUtils"; import * as list from "./list"; -export async function showProblem(node?: LeetCodeNode): Promise { +export async function showProblem(node?: LeetCodeNode, withTagFloder?: boolean): Promise { if (!node) { return; } - await showProblemInternal(node.id); + await showProblemInternal(node.id, withTagFloder); } export async function searchProblem(): Promise { @@ -37,7 +37,7 @@ export async function searchProblem(): Promise { await showProblemInternal(choice.value); } -async function showProblemInternal(id: string): Promise { +async function showProblemInternal(id: string, withTagFloder?: boolean): Promise { try { const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode"); let defaultLanguage: string | undefined = leetCodeConfig.get("defaultLanguage"); @@ -49,7 +49,11 @@ async function showProblemInternal(id: string): Promise { return; } - const outDir: string = await selectWorkspaceFolder(); + let outDir: string = await selectWorkspaceFolder(); + if (withTagFloder) { + const { tags } = await leetCodeExecutor.getCompaniesAndTags(); + outDir = `${outDir}/${tags[id][0].split("-").map((c: string) => c[0].toUpperCase() + c.slice(1)).join(" ")}`; + } await fse.ensureDir(outDir); const result: string = await leetCodeExecutor.showProblem(id, language, outDir); const reg: RegExp = /\* Source Code:\s*(.*)/; diff --git a/src/extension.ts b/src/extension.ts index 9685b3f4..5b9c71bd 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -43,6 +43,7 @@ export async function activate(context: vscode.ExtensionContext): Promise vscode.commands.registerCommand("leetcode.selectSessions", () => session.selectSession()), vscode.commands.registerCommand("leetcode.createSession", () => session.createSession()), vscode.commands.registerCommand("leetcode.showProblem", (node: LeetCodeNode) => show.showProblem(node)), + vscode.commands.registerCommand("leetcode.showProblemWithTag", (node: LeetCodeNode) => show.showProblem(node, true)), vscode.commands.registerCommand("leetcode.searchProblem", () => show.searchProblem()), vscode.commands.registerCommand("leetcode.refreshExplorer", () => leetCodeTreeDataProvider.refresh()), vscode.commands.registerCommand("leetcode.testSolution", (uri?: vscode.Uri) => test.testSolution(uri)), From 99dcf76dc71287ecd2ea00b158db6eaf7d5da522 Mon Sep 17 00:00:00 2001 From: chengruilin Date: Wed, 13 Feb 2019 20:49:44 +0800 Subject: [PATCH 02/11] feat: add outputPath config --- README.md | 7 +++++-- docs/README_zh-CN.md | 3 +-- package.json | 22 ++++++++++++---------- src/commands/show.ts | 26 ++++++++++++++++++++------ src/extension.ts | 1 - 5 files changed, 38 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index e3ccab02..159f1adb 100644 --- a/README.md +++ b/README.md @@ -67,8 +67,7 @@ Pick a Problem

-- Right click the problem in the `LeetCode Explorer` and select `Show problem` will generate a new file with the problem description for you. -- Right click the problem in the `LeetCode Explorer` and select `Show problem with tag` will generate a new file with the problem description and classified by tag folder. +- Right click the problem in the `LeetCode Explorer` and select `Show Problem` will generate a new file with the problem description for you. > Note: If no folder is opened in VS Code, the extension will save the problem files in **$HOME/.leetcode/**. @@ -122,6 +121,10 @@ | `leetcode.defaultLanguage` | Specify the default language used to solve the problem. Supported languages are: `bash`, `c`, `cpp`, `csharp`, `golang`, `java`, `javascript`, `kotlin`, `mysql`, `python`,`python3`,`ruby`,`scala`,`swift` | `N/A` | | `leetcode.useWsl` | Specify whether to use WSL or not | `false` | | `leetcode.endpoint` | Specify the active endpoint. Supported endpoints are: `leetcode`, `leetcode-cn` | `leetcode` | +| `leetcode.outputPath` | * `${tag}` - a directory based on the problem's tag. For example, if the problem belongs to: `Binary Indexed Tree`, then a folder named `binary_indexed_tree` will be used here. | +* `${language}` - a directory based on the language used. For example, `java` for Java language +* `${difficulty}` - a directory based on the problem's difficulty. For example, `easy` +* If this setting is not set, the files will be generated to the base path of the workspace folder | `root` | ## Release Notes diff --git a/docs/README_zh-CN.md b/docs/README_zh-CN.md index 200e669f..1ed7f27a 100644 --- a/docs/README_zh-CN.md +++ b/docs/README_zh-CN.md @@ -67,8 +67,7 @@ 选择题目

-- 在 `LeetCode Explorer` 中**右键**题目并选择 `Show problem` 进行答题。 -- 在 `LeetCode Explorer` 中**右键**题目并选择 `Show problem with tag`,题目会被放进分类好的文件夹,并进行答题。 +- 在 `LeetCode Explorer` 中**右键**题目并选择 `Show Problem` 进行答题。 > 注意:若当前 VS Code 没有已打开的文件夹,则生成的题目文件会存储于 **$HOME/.leetcode/** 目录下。 diff --git a/package.json b/package.json index e8cdfb2b..9d5f0797 100644 --- a/package.json +++ b/package.json @@ -93,11 +93,6 @@ "title": "Show Problem", "category": "LeetCode" }, - { - "command": "leetcode.showProblemWithTag", - "title": "Show problem with tag", - "category": "LeetCode" - }, { "command": "leetcode.searchProblem", "title": "Search Problem", @@ -163,11 +158,6 @@ "command": "leetcode.showProblem", "when": "view == leetCodeExplorer && viewItem == problem", "group": "leetcode@1" - }, - { - "command": "leetcode.showProblemWithTag", - "when": "view == leetCodeExplorer && viewItem == problem", - "group": "leetcode@1" } ], "commandPalette": [ @@ -257,6 +247,18 @@ "leetcode-cn" ], "description": "Endpoint of the user account." + }, + "leetcode.outputPath": { + "type": "string", + "default": "root", + "scope": "application", + "enum": [ + "root", + "tag", + "language", + "difficulty" + ], + "description": "Specifies the relative path to save the problem files." } } } diff --git a/src/commands/show.ts b/src/commands/show.ts index a8ca82a6..0f4af83c 100644 --- a/src/commands/show.ts +++ b/src/commands/show.ts @@ -12,11 +12,11 @@ import { selectWorkspaceFolder } from "../utils/workspaceUtils"; import * as wsl from "../utils/wslUtils"; import * as list from "./list"; -export async function showProblem(node?: LeetCodeNode, withTagFloder?: boolean): Promise { +export async function showProblem(node?: LeetCodeNode): Promise { if (!node) { return; } - await showProblemInternal(node.id, withTagFloder); + await showProblemInternal(node.id); } export async function searchProblem(): Promise { @@ -37,7 +37,7 @@ export async function searchProblem(): Promise { await showProblemInternal(choice.value); } -async function showProblemInternal(id: string, withTagFloder?: boolean): Promise { +async function showProblemInternal(id: string): Promise { try { const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode"); let defaultLanguage: string | undefined = leetCodeConfig.get("defaultLanguage"); @@ -50,9 +50,23 @@ async function showProblemInternal(id: string, withTagFloder?: boolean): Promise } let outDir: string = await selectWorkspaceFolder(); - if (withTagFloder) { - const { tags } = await leetCodeExecutor.getCompaniesAndTags(); - outDir = `${outDir}/${tags[id][0].split("-").map((c: string) => c[0].toUpperCase() + c.slice(1)).join(" ")}`; + const outputPath: string = leetCodeConfig.get("outputPath") || "root"; + switch (outputPath) { + case "root": { + break; + } + case "tag": { + const { tags } = await leetCodeExecutor.getCompaniesAndTags(); + outDir = `${outDir}/${tags[id][0].split("-").map((c: string) => c[0].toUpperCase() + c.slice(1)).join("")}`; + break; + } + case "language": { + outDir = `${outDir}/${language}`; + break; + } + case "difficulty": { + break; + } } await fse.ensureDir(outDir); const result: string = await leetCodeExecutor.showProblem(id, language, outDir); diff --git a/src/extension.ts b/src/extension.ts index 5b9c71bd..9685b3f4 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -43,7 +43,6 @@ export async function activate(context: vscode.ExtensionContext): Promise vscode.commands.registerCommand("leetcode.selectSessions", () => session.selectSession()), vscode.commands.registerCommand("leetcode.createSession", () => session.createSession()), vscode.commands.registerCommand("leetcode.showProblem", (node: LeetCodeNode) => show.showProblem(node)), - vscode.commands.registerCommand("leetcode.showProblemWithTag", (node: LeetCodeNode) => show.showProblem(node, true)), vscode.commands.registerCommand("leetcode.searchProblem", () => show.searchProblem()), vscode.commands.registerCommand("leetcode.refreshExplorer", () => leetCodeTreeDataProvider.refresh()), vscode.commands.registerCommand("leetcode.testSolution", (uri?: vscode.Uri) => test.testSolution(uri)), From 99cb09b731c3a14cfc595509b121a296f5db48b0 Mon Sep 17 00:00:00 2001 From: chengruilin Date: Thu, 14 Feb 2019 20:06:51 +0800 Subject: [PATCH 03/11] feat: update outputPath api --- README.md | 21 ++++++++++----------- package.json | 8 +------- src/commands/show.ts | 24 +++++++++++++++++------- 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index 159f1adb..5a8c9416 100644 --- a/README.md +++ b/README.md @@ -114,17 +114,16 @@ ## Settings -| Setting Name | Description | Default Value | -| -------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -| `leetcode.hideSolved` | Specify to hide the solved problems or not | `false` | -| `leetcode.showLocked` | Specify to show the locked problems or not. Only Premium users could open the locked problems | `false` | -| `leetcode.defaultLanguage` | Specify the default language used to solve the problem. Supported languages are: `bash`, `c`, `cpp`, `csharp`, `golang`, `java`, `javascript`, `kotlin`, `mysql`, `python`,`python3`,`ruby`,`scala`,`swift` | `N/A` | -| `leetcode.useWsl` | Specify whether to use WSL or not | `false` | -| `leetcode.endpoint` | Specify the active endpoint. Supported endpoints are: `leetcode`, `leetcode-cn` | `leetcode` | -| `leetcode.outputPath` | * `${tag}` - a directory based on the problem's tag. For example, if the problem belongs to: `Binary Indexed Tree`, then a folder named `binary_indexed_tree` will be used here. | -* `${language}` - a directory based on the language used. For example, `java` for Java language -* `${difficulty}` - a directory based on the problem's difficulty. For example, `easy` -* If this setting is not set, the files will be generated to the base path of the workspace folder | `root` | +| Setting Name | Description | Default Value | +|---|---|---| +| `leetcode.hideSolved` | Specify to hide the solved problems or not | `false` | +| `leetcode.showLocked` | Specify to show the locked problems or not. Only Premium users could open the locked problems | `false` | +| `leetcode.defaultLanguage` | Specify the default language used to solve the problem. Supported languages are: `bash`, `c`, `cpp`, `csharp`, `golang`, `java`, `javascript`, `kotlin`, `mysql`, `python`,`python3`,`ruby`,`scala`,`swift` | `N/A` | +| `leetcode.useWsl` | Specify whether to use WSL or not | `false` | +| `leetcode.endpoint` | Specify the active endpoint. Supported endpoints are: `leetcode`, `leetcode-cn` | `leetcode` | + +## Troubleshooting +When you meet any problem, you can check the [Troubleshooting page](https://github.com/jdneo/vscode-leetcode/wiki/Troubleshooting) first. ## Release Notes diff --git a/package.json b/package.json index 9d5f0797..1caf0e56 100644 --- a/package.json +++ b/package.json @@ -250,14 +250,8 @@ }, "leetcode.outputPath": { "type": "string", - "default": "root", + "default": "", "scope": "application", - "enum": [ - "root", - "tag", - "language", - "difficulty" - ], "description": "Specifies the relative path to save the problem files." } } diff --git a/src/commands/show.ts b/src/commands/show.ts index 0f4af83c..f1c47149 100644 --- a/src/commands/show.ts +++ b/src/commands/show.ts @@ -39,6 +39,7 @@ export async function searchProblem(): Promise { async function showProblemInternal(id: string): Promise { try { + const listProblems: IProblem[] = await list.listProblems(); const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode"); let defaultLanguage: string | undefined = leetCodeConfig.get("defaultLanguage"); if (defaultLanguage && languages.indexOf(defaultLanguage) < 0) { @@ -50,21 +51,30 @@ async function showProblemInternal(id: string): Promise { } let outDir: string = await selectWorkspaceFolder(); - const outputPath: string = leetCodeConfig.get("outputPath") || "root"; + const outputPath: string = leetCodeConfig.get("outputPath") || ""; + const problem: IProblem | undefined = listProblems.find((item: IProblem) => item.id === id); switch (outputPath) { - case "root": { + case "": { break; } - case "tag": { - const { tags } = await leetCodeExecutor.getCompaniesAndTags(); - outDir = `${outDir}/${tags[id][0].split("-").map((c: string) => c[0].toUpperCase() + c.slice(1)).join("")}`; + case "${tag}": { + if (problem) { + outDir = `${outDir}/${problem.tags[0]}`; + } break; } - case "language": { + case "${language}": { outDir = `${outDir}/${language}`; break; } - case "difficulty": { + case "${difficulty}": { + if (problem) { + outDir = `${outDir}/${problem.difficulty}`; + } + break; + } + default: { + outDir = `${outDir}/${outputPath}`; break; } } From cf72574319c703387d4cb3fabb80d9c9a4c5fe9e Mon Sep 17 00:00:00 2001 From: chengruilin Date: Thu, 14 Feb 2019 20:16:16 +0800 Subject: [PATCH 04/11] chore: revert chinese README --- docs/README_zh-CN.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/README_zh-CN.md b/docs/README_zh-CN.md index 1ed7f27a..c91f8860 100644 --- a/docs/README_zh-CN.md +++ b/docs/README_zh-CN.md @@ -114,13 +114,13 @@ ## 插件配置项 -| 配置项名称 | 描述 | 默认值 | -| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- | -| `leetcode.hideSolved` | 指定是否要隐藏已解决的问题 | `false` | -| `leetcode.showLocked` | 指定是否显示付费题目,只有付费账户才可以打开付费题目 | `false` | -| `leetcode.defaultLanguage` | 指定答题时使用的默认语言,可选语言有:`bash`, `c`, `cpp`, `csharp`, `golang`, `java`, `javascript`, `kotlin`, `mysql`, `python`,`python3`,`ruby`,`scala`,`swift` | `N/A` | -| `leetcode.useWsl` | 指定是否启用 WSL | `false` | -| `leetcode.endpoint` | 指定使用的终端,可用终端有:`leetcode`, `leetcode-cn` | `leetcode` | +| 配置项名称 | 描述 | 默认值 | +|---|---|---| +| `leetcode.hideSolved` | 指定是否要隐藏已解决的问题 | `false` | +| `leetcode.showLocked` | 指定是否显示付费题目,只有付费账户才可以打开付费题目 | `false` | +| `leetcode.defaultLanguage` | 指定答题时使用的默认语言,可选语言有:`bash`, `c`, `cpp`, `csharp`, `golang`, `java`, `javascript`, `kotlin`, `mysql`, `python`,`python3`,`ruby`,`scala`,`swift` | `N/A` | +| `leetcode.useWsl` | 指定是否启用 WSL | `false` | +| `leetcode.endpoint` | 指定使用的终端,可用终端有:`leetcode`, `leetcode-cn` | `leetcode` | ## 更新日志 From 96487df6467db810cde62bf18e1c18b823f8b5f3 Mon Sep 17 00:00:00 2001 From: chengruilin Date: Fri, 15 Feb 2019 19:52:44 +0800 Subject: [PATCH 05/11] refactor: treat with the outputPath --- package.json | 3 +-- src/commands/show.ts | 63 ++++++++++++++++++++++---------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index 1caf0e56..83ab92fe 100644 --- a/package.json +++ b/package.json @@ -250,9 +250,8 @@ }, "leetcode.outputPath": { "type": "string", - "default": "", "scope": "application", - "description": "Specifies the relative path to save the problem files." + "description": "Specify the relative path to save the problem files." } } } diff --git a/src/commands/show.ts b/src/commands/show.ts index f1c47149..59f1bdc7 100644 --- a/src/commands/show.ts +++ b/src/commands/show.ts @@ -2,6 +2,7 @@ // Licensed under the MIT license. import * as fse from "fs-extra"; +import * as path from "path"; import * as vscode from "vscode"; import { LeetCodeNode } from "../explorer/LeetCodeNode"; import { leetCodeExecutor } from "../leetCodeExecutor"; @@ -16,7 +17,7 @@ export async function showProblem(node?: LeetCodeNode): Promise { if (!node) { return; } - await showProblemInternal(node.id); + await showProblemInternal(node); } export async function searchProblem(): Promise { @@ -24,8 +25,9 @@ export async function searchProblem(): Promise { promptForSignIn(); return; } + const problems: IProblem[] = await list.listProblems(); const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick( - parseProblemsToPicks(list.listProblems()), + parseProblemsToPicks(problems), { matchOnDetail: true, placeHolder: "Select one problem", @@ -34,12 +36,11 @@ export async function searchProblem(): Promise { if (!choice) { return; } - await showProblemInternal(choice.value); + await showProblemInternal(problems.find((problem: IProblem) => problem.id === choice.value) as IProblem); } -async function showProblemInternal(id: string): Promise { +async function showProblemInternal(node: IProblem): Promise { try { - const listProblems: IProblem[] = await list.listProblems(); const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode"); let defaultLanguage: string | undefined = leetCodeConfig.get("defaultLanguage"); if (defaultLanguage && languages.indexOf(defaultLanguage) < 0) { @@ -51,35 +52,35 @@ async function showProblemInternal(id: string): Promise { } let outDir: string = await selectWorkspaceFolder(); - const outputPath: string = leetCodeConfig.get("outputPath") || ""; - const problem: IProblem | undefined = listProblems.find((item: IProblem) => item.id === id); - switch (outputPath) { - case "": { - break; - } - case "${tag}": { - if (problem) { - outDir = `${outDir}/${problem.tags[0]}`; + const outputPathCfg: string = leetCodeConfig.get("outputPath") || ""; + const outputPath: RegExpMatchArray | null = outputPathCfg.match(/\$\{(.*?)\}/); + if (outputPath) { + switch (outputPath[1].toLowerCase()) { + case "tag": { + const closestTag: string = node.tags.reduce((prev: string, curr: string) => { + return curr.length > prev.length ? + curr : + prev; + }, ""); + outDir = path.join(outDir, closestTag); + break; } - break; - } - case "${language}": { - outDir = `${outDir}/${language}`; - break; - } - case "${difficulty}": { - if (problem) { - outDir = `${outDir}/${problem.difficulty}`; + case "language": { + outDir = path.join(outDir, language); + break; } - break; - } - default: { - outDir = `${outDir}/${outputPath}`; - break; + case "difficulty": { + outDir = path.join(outDir, node.difficulty); + break; + } + default: { + break; + } + } } await fse.ensureDir(outDir); - const result: string = await leetCodeExecutor.showProblem(id, language, outDir); + const result: string = await leetCodeExecutor.showProblem(node.id, language, outDir); const reg: RegExp = /\* Source Code:\s*(.*)/; const match: RegExpMatchArray | null = result.match(reg); if (match && match.length >= 2) { @@ -108,9 +109,9 @@ async function showProblemInternal(id: string): Promise { } } -async function parseProblemsToPicks(p: Promise): Promise>> { +async function parseProblemsToPicks(p: IProblem[]): Promise>> { return new Promise(async (resolve: (res: Array>) => void): Promise => { - const picks: Array> = (await p).map((problem: IProblem) => Object.assign({}, { + const picks: Array> = p.map((problem: IProblem) => Object.assign({}, { label: `${parseProblemDecorator(problem.state, problem.locked)}${problem.id}.${problem.name}`, description: "", detail: `AC rate: ${problem.passRate}, Difficulty: ${problem.difficulty}`, From 3b7a86a6d974320098ff0849047a57ce4d8cf335 Mon Sep 17 00:00:00 2001 From: chengruilin Date: Fri, 15 Feb 2019 21:38:32 +0800 Subject: [PATCH 06/11] refactor: Update judgment condition --- src/commands/show.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/commands/show.ts b/src/commands/show.ts index 59f1bdc7..bfa86c28 100644 --- a/src/commands/show.ts +++ b/src/commands/show.ts @@ -56,7 +56,7 @@ async function showProblemInternal(node: IProblem): Promise { const outputPath: RegExpMatchArray | null = outputPathCfg.match(/\$\{(.*?)\}/); if (outputPath) { switch (outputPath[1].toLowerCase()) { - case "tag": { + case "tag": const closestTag: string = node.tags.reduce((prev: string, curr: string) => { return curr.length > prev.length ? curr : @@ -64,20 +64,19 @@ async function showProblemInternal(node: IProblem): Promise { }, ""); outDir = path.join(outDir, closestTag); break; - } - case "language": { + case "language": outDir = path.join(outDir, language); break; - } - case "difficulty": { + case "difficulty": outDir = path.join(outDir, node.difficulty); break; - } default: { break; } } + } else { + outDir = path.join(outDir, outputPathCfg); } await fse.ensureDir(outDir); const result: string = await leetCodeExecutor.showProblem(node.id, language, outDir); From f6352cdc13c1abd934452e726969f08d717d8851 Mon Sep 17 00:00:00 2001 From: chengruilin Date: Sat, 16 Feb 2019 15:38:29 +0800 Subject: [PATCH 07/11] feat: add tag selector --- src/commands/show.ts | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/commands/show.ts b/src/commands/show.ts index bfa86c28..e50f2dbc 100644 --- a/src/commands/show.ts +++ b/src/commands/show.ts @@ -26,7 +26,7 @@ export async function searchProblem(): Promise { return; } const problems: IProblem[] = await list.listProblems(); - const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick( + const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick( parseProblemsToPicks(problems), { matchOnDetail: true, @@ -36,7 +36,7 @@ export async function searchProblem(): Promise { if (!choice) { return; } - await showProblemInternal(problems.find((problem: IProblem) => problem.id === choice.value) as IProblem); + await showProblemInternal(choice.value); } async function showProblemInternal(node: IProblem): Promise { @@ -57,12 +57,22 @@ async function showProblemInternal(node: IProblem): Promise { if (outputPath) { switch (outputPath[1].toLowerCase()) { case "tag": - const closestTag: string = node.tags.reduce((prev: string, curr: string) => { - return curr.length > prev.length ? - curr : - prev; - }, ""); - outDir = path.join(outDir, closestTag); + let tag: string | undefined; + if (node.tags.length === 1) { + tag = node.tags[0]; + } else { + tag = await vscode.window.showQuickPick( + node.tags, + { + matchOnDetail: true, + placeHolder: "Select one tag", + }, + ); + } + if (!tag) { + return; + } + outDir = path.join(outDir, tag); break; case "language": outDir = path.join(outDir, language); @@ -108,13 +118,13 @@ async function showProblemInternal(node: IProblem): Promise { } } -async function parseProblemsToPicks(p: IProblem[]): Promise>> { - return new Promise(async (resolve: (res: Array>) => void): Promise => { - const picks: Array> = p.map((problem: IProblem) => Object.assign({}, { +async function parseProblemsToPicks(p: IProblem[]): Promise>> { + return new Promise(async (resolve: (res: Array>) => void): Promise => { + const picks: Array> = p.map((problem: IProblem) => Object.assign({}, { label: `${parseProblemDecorator(problem.state, problem.locked)}${problem.id}.${problem.name}`, description: "", detail: `AC rate: ${problem.passRate}, Difficulty: ${problem.difficulty}`, - value: problem.id, + value: problem, })); resolve(picks); }); From 3a688cd12749e58a73925c23e16dabf19bc6be57 Mon Sep 17 00:00:00 2001 From: "sheche@microsoft.com" Date: Sat, 16 Feb 2019 20:29:34 +0800 Subject: [PATCH 08/11] Refactoring --- src/commands/show.ts | 79 ++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/src/commands/show.ts b/src/commands/show.ts index e50f2dbc..edb3ad0c 100644 --- a/src/commands/show.ts +++ b/src/commands/show.ts @@ -5,6 +5,7 @@ import * as fse from "fs-extra"; import * as path from "path"; import * as vscode from "vscode"; import { LeetCodeNode } from "../explorer/LeetCodeNode"; +import { leetCodeChannel } from "../leetCodeChannel"; import { leetCodeExecutor } from "../leetCodeExecutor"; import { leetCodeManager } from "../leetCodeManager"; import { IProblem, IQuickItemEx, languages, ProblemState } from "../shared"; @@ -25,9 +26,8 @@ export async function searchProblem(): Promise { promptForSignIn(); return; } - const problems: IProblem[] = await list.listProblems(); const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick( - parseProblemsToPicks(problems), + parseProblemsToPicks(list.listProblems()), { matchOnDetail: true, placeHolder: "Select one problem", @@ -52,42 +52,18 @@ async function showProblemInternal(node: IProblem): Promise { } let outDir: string = await selectWorkspaceFolder(); - const outputPathCfg: string = leetCodeConfig.get("outputPath") || ""; - const outputPath: RegExpMatchArray | null = outputPathCfg.match(/\$\{(.*?)\}/); - if (outputPath) { - switch (outputPath[1].toLowerCase()) { - case "tag": - let tag: string | undefined; - if (node.tags.length === 1) { - tag = node.tags[0]; - } else { - tag = await vscode.window.showQuickPick( - node.tags, - { - matchOnDetail: true, - placeHolder: "Select one tag", - }, - ); - } - if (!tag) { - return; - } - outDir = path.join(outDir, tag); - break; - case "language": - outDir = path.join(outDir, language); - break; - case "difficulty": - outDir = path.join(outDir, node.difficulty); - break; - default: { - break; - } - + let relativePath: string = (leetCodeConfig.get("outputPath") || "").trim(); + const matchResult: RegExpMatchArray | null = relativePath.match(/\$\{(.*?)\}/); + if (matchResult) { + const resolvedPath: string | undefined = await resolveRelativePath(matchResult[1].toLocaleLowerCase(), node, language); + if (!resolvedPath) { + leetCodeChannel.appendLine("No tag is picked, skip showing the problem."); + return; } - } else { - outDir = path.join(outDir, outputPathCfg); + relativePath = resolvedPath; } + + outDir = path.join(outDir, relativePath); await fse.ensureDir(outDir); const result: string = await leetCodeExecutor.showProblem(node.id, language, outDir); const reg: RegExp = /\* Source Code:\s*(.*)/; @@ -114,13 +90,13 @@ async function showProblemInternal(node: IProblem): Promise { } } } catch (error) { - await promptForOpenOutputChannel("Failed to fetch the problem information. Please open the output channel for details.", DialogType.error); + await promptForOpenOutputChannel("Failed to show the problem. Please open the output channel for details.", DialogType.error); } } -async function parseProblemsToPicks(p: IProblem[]): Promise>> { +async function parseProblemsToPicks(p: Promise): Promise>> { return new Promise(async (resolve: (res: Array>) => void): Promise => { - const picks: Array> = p.map((problem: IProblem) => Object.assign({}, { + const picks: Array> = (await p).map((problem: IProblem) => Object.assign({}, { label: `${parseProblemDecorator(problem.state, problem.locked)}${problem.id}.${problem.name}`, description: "", detail: `AC rate: ${problem.passRate}, Difficulty: ${problem.difficulty}`, @@ -140,3 +116,28 @@ function parseProblemDecorator(state: ProblemState, locked: boolean): string { return locked ? "$(lock) " : ""; } } + +async function resolveRelativePath(value: string, node: IProblem, selectedLanguage: string): Promise { + switch (value) { + case "tag": + if (node.tags.length === 1) { + return node.tags[0]; + } + return await vscode.window.showQuickPick( + node.tags, + { + matchOnDetail: true, + placeHolder: "Select one tag", + ignoreFocusOut: true, + }, + ); + case "language": + return selectedLanguage; + case "difficulty": + return node.difficulty; + default: + const errorMsg: string = `The config '${value}' is not supported.`; + leetCodeChannel.appendLine(errorMsg); + throw new Error(errorMsg); + } +} From a7afe9c5ec952e4f511aa59548a2e4e6431e86da Mon Sep 17 00:00:00 2001 From: "sheche@microsoft.com" Date: Sat, 16 Feb 2019 20:36:39 +0800 Subject: [PATCH 09/11] Refine wording --- src/commands/show.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/show.ts b/src/commands/show.ts index edb3ad0c..da0fa525 100644 --- a/src/commands/show.ts +++ b/src/commands/show.ts @@ -127,7 +127,7 @@ async function resolveRelativePath(value: string, node: IProblem, selectedLangua node.tags, { matchOnDetail: true, - placeHolder: "Select one tag", + placeHolder: "Multiple tags available, please select one", ignoreFocusOut: true, }, ); From 8c2280532b5ff3d1831242687adefb250b969b01 Mon Sep 17 00:00:00 2001 From: "sheche@microsoft.com" Date: Sat, 16 Feb 2019 20:42:16 +0800 Subject: [PATCH 10/11] Refine the wording --- src/commands/show.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/show.ts b/src/commands/show.ts index da0fa525..b1daca98 100644 --- a/src/commands/show.ts +++ b/src/commands/show.ts @@ -57,7 +57,7 @@ async function showProblemInternal(node: IProblem): Promise { if (matchResult) { const resolvedPath: string | undefined = await resolveRelativePath(matchResult[1].toLocaleLowerCase(), node, language); if (!resolvedPath) { - leetCodeChannel.appendLine("No tag is picked, skip showing the problem."); + leetCodeChannel.appendLine("Showing problem canceled by user."); return; } relativePath = resolvedPath; From 3e3cb77562b09d1f12f6ea37c83dad56cf31943f Mon Sep 17 00:00:00 2001 From: "sheche@microsoft.com" Date: Sat, 16 Feb 2019 20:51:16 +0800 Subject: [PATCH 11/11] Change the setting name --- package.json | 2 +- src/commands/show.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 7a9948e8..54ff1440 100644 --- a/package.json +++ b/package.json @@ -248,7 +248,7 @@ ], "description": "Endpoint of the user account." }, - "leetcode.outputPath": { + "leetcode.outputFolder": { "type": "string", "scope": "application", "description": "Specify the relative path to save the problem files." diff --git a/src/commands/show.ts b/src/commands/show.ts index b1daca98..f9796621 100644 --- a/src/commands/show.ts +++ b/src/commands/show.ts @@ -52,7 +52,7 @@ async function showProblemInternal(node: IProblem): Promise { } let outDir: string = await selectWorkspaceFolder(); - let relativePath: string = (leetCodeConfig.get("outputPath") || "").trim(); + let relativePath: string = (leetCodeConfig.get("outputFolder") || "").trim(); const matchResult: RegExpMatchArray | null = relativePath.match(/\$\{(.*?)\}/); if (matchResult) { const resolvedPath: string | undefined = await resolveRelativePath(matchResult[1].toLocaleLowerCase(), node, language);