Skip to content

Commit e1f3206

Browse files
authored
feat: Can select folder to save the LeetCode files (#365)
1 parent a00dac5 commit e1f3206

File tree

6 files changed

+64
-8
lines changed

6 files changed

+64
-8
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@
121121
| `leetcode.defaultLanguage` | Specify the default language used to solve the problem. Supported languages are: `bash`, `c`, `cpp`, `csharp`, `golang`, `java`, `javascript`, `kotlin`, `mysql`, `php`, `python`,`python3`,`ruby`,`rust`, `scala`,`swift` | `N/A` |
122122
| `leetcode.useWsl` | Specify whether to use WSL or not | `false` |
123123
| `leetcode.endpoint` | Specify the active endpoint. Supported endpoints are: `leetcode`, `leetcode-cn` | `leetcode` |
124-
| `leetcode.workspaceFolder` | Specify the path of the workspace folder to store the problem files. | `${home}/.leetcode` |
124+
| `leetcode.workspaceFolder` | Specify the path of the workspace folder to store the problem files. | `""` |
125125
| `leetcode.outputFolder` | Specify the relative path to save the problem files. Besides using customized path, there are also several reserved words which can be used here: <ul><li>`${tag}`: Categorize the problem according to their tags.<li>`${language}`: Categorize the problem according to their language.</li><li>`${difficulty}`: Categorize the problem according to their difficulty.</li></ul>For example: `problem-${tag}-${difficulty}` | N/A |
126126
| `leetcode.enableStatusBar` | Specify whether the LeetCode status bar will be shown or not. | `true` |
127127
| **(Deprecated)** `leetcode.enableShortcuts` | Specify whether the submit and test shortcuts in editor or not. | `true` |

docs/README_zh-CN.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@
121121
| `leetcode.defaultLanguage` | 指定答题时使用的默认语言,可选语言有:`bash`, `c`, `cpp`, `csharp`, `golang`, `java`, `javascript`, `kotlin`, `mysql`, `php`, `python`,`python3`,`ruby`, `rust`, `scala`,`swift` | `N/A` |
122122
| `leetcode.useWsl` | 指定是否启用 WSL | `false` |
123123
| `leetcode.endpoint` | 指定使用的终端,可用终端有:`leetcode`, `leetcode-cn` | `leetcode` |
124-
| `leetcode.workspaceFolder` | 指定保存文件的工作区目录 | `${home}/.leetcode` |
124+
| `leetcode.workspaceFolder` | 指定保存文件的工作区目录 | `""` |
125125
| `leetcode.outputFolder` | 指定保存文件时所用的相对文件夹路径。除了用户自定义路径外,也可以使用保留项,包括:<ul><li>`${tag}`: 根据题目的类别进行分类。<li>`${language}`: 根据题目的语言进行分类。</li><li>`${difficulty}`: 根据题目的难度进行分类。</li></ul>例如:`problem-${tag}-${difficulty}` | N/A |
126126
| `leetcode.enableStatusBar` | 指定是否在 VS Code 下方显示插件状态栏。 | `true` |
127127
| **(Deprecated)** `leetcode.enableShortcuts` | 指定是否在 VS Code 编辑文件下方显示提交和测试的快捷按钮。 | `true` |

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@
314314
"type": "string",
315315
"scope": "application",
316316
"description": "The path of the workspace folder to store the problem files.",
317-
"default": "${home}/.leetcode"
317+
"default": ""
318318
},
319319
"leetcode.outputFolder": {
320320
"type": "string",

src/utils/settingUtils.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright (c) jdneo. All rights reserved.
22
// Licensed under the MIT license.
33

4-
import * as os from "os";
54
import { workspace, WorkspaceConfiguration } from "vscode";
65

76
export function getWorkspaceConfiguration(): WorkspaceConfiguration {
@@ -13,8 +12,7 @@ export function shouldHideSolvedProblem(): boolean {
1312
}
1413

1514
export function getWorkspaceFolder(): string {
16-
const rawWorkspaceFolder: string = getWorkspaceConfiguration().get<string>("workspaceFolder", "${home}/.leetcode");
17-
return rawWorkspaceFolder.replace(/\${home}/i, os.homedir());
15+
return getWorkspaceConfiguration().get<string>("workspaceFolder", "");
1816
}
1917

2018
export function getEditorShortcuts(): string[] {

src/utils/uiUtils.ts

+12
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,18 @@ export async function showFileSelectDialog(): Promise<vscode.Uri[] | undefined>
9292
return await vscode.window.showOpenDialog(options);
9393
}
9494

95+
export async function showDirectorySelectDialog(): Promise<vscode.Uri[] | undefined> {
96+
const defaultUri: vscode.Uri | undefined = vscode.workspace.rootPath ? vscode.Uri.file(vscode.workspace.rootPath) : undefined;
97+
const options: vscode.OpenDialogOptions = {
98+
defaultUri,
99+
canSelectFiles: false,
100+
canSelectFolders: true,
101+
canSelectMany: false,
102+
openLabel: "Select",
103+
};
104+
return await vscode.window.showOpenDialog(options);
105+
}
106+
95107
export async function openUrl(url: string): Promise<void> {
96108
vscode.commands.executeCommand("vscode.open", vscode.Uri.parse(url));
97109
}

src/utils/workspaceUtils.ts

+48-2
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
// Copyright (c) jdneo. All rights reserved.
22
// Licensed under the MIT license.
33

4+
import * as os from "os";
45
import * as path from "path";
56
import * as vscode from "vscode";
6-
import { getWorkspaceFolder } from "./settingUtils";
7+
import { IQuickItemEx } from "../shared";
8+
import { getWorkspaceConfiguration, getWorkspaceFolder } from "./settingUtils";
9+
import { showDirectorySelectDialog } from "./uiUtils";
710
import * as wsl from "./wslUtils";
811

912
export async function selectWorkspaceFolder(): Promise<string> {
10-
const workspaceFolderSetting: string = getWorkspaceFolder();
13+
let workspaceFolderSetting: string = getWorkspaceFolder();
14+
if (workspaceFolderSetting.trim() === "") {
15+
workspaceFolderSetting = await determineLeetCodeFolder();
16+
if (workspaceFolderSetting === "") {
17+
// User cancelled
18+
return workspaceFolderSetting;
19+
}
20+
}
1121
const workspaceFolders: vscode.WorkspaceFolder[] = vscode.workspace.workspaceFolders || [];
1222
let needAsk: boolean = true;
1323
for (const folder of workspaceFolders) {
@@ -70,6 +80,42 @@ function isSubFolder(from: string, to: string): boolean {
7080
return !relative.startsWith("..") && !path.isAbsolute(relative);
7181
}
7282

83+
async function determineLeetCodeFolder(): Promise<string> {
84+
let result: string;
85+
const picks: Array<IQuickItemEx<string>> = [];
86+
picks.push(
87+
{
88+
label: `Default location`,
89+
detail: `${path.join(os.homedir(), ".leetcode")}`,
90+
value: `${path.join(os.homedir(), ".leetcode")}`,
91+
},
92+
{
93+
label: "$(file-directory) Browse...",
94+
value: ":browse",
95+
},
96+
);
97+
const choice: IQuickItemEx<string> | undefined = await vscode.window.showQuickPick(
98+
picks,
99+
{ placeHolder: "Select where you would like to save your LeetCode files" },
100+
);
101+
if (!choice) {
102+
result = "";
103+
} else if (choice.value === ":browse") {
104+
const directory: vscode.Uri[] | undefined = await showDirectorySelectDialog();
105+
if (!directory || directory.length < 1) {
106+
result = "";
107+
} else {
108+
result = directory[0].fsPath;
109+
}
110+
} else {
111+
result = choice.value;
112+
}
113+
114+
getWorkspaceConfiguration().update("workspaceFolder", result, vscode.ConfigurationTarget.Global);
115+
116+
return result;
117+
}
118+
73119
enum OpenOption {
74120
openInCurrentWindow = "Open in current window",
75121
openInNewWindow = "Open in new window",

0 commit comments

Comments
 (0)