Skip to content

Commit 453c51a

Browse files
authored
feat: Can specify the workspace folder to save the files (#360)
1 parent 4abd6fc commit 453c51a

File tree

6 files changed

+63
-13
lines changed

6 files changed

+63
-13
lines changed

README.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
- Directly click on the problem or right click the problem in the `LeetCode Explorer` and select `Preview Problem` to see the problem description.
7474
- Select `Show Problem` to directly open the file with the problem description.
7575

76-
> Note: If no folder is opened in VS Code, the extension will save the problem files in **$HOME/.leetcode/**.
76+
> Note:You can specify the path of the workspace folder to store the problem files by updating the setting `leetcode.workspaceFolder`. The default value is:**$HOME/.leetcode/**.
7777
7878
> You can specify whether including the problem description in comments or not by updating the setting `leetcode.showCommentDescription`.
7979
@@ -121,6 +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` |
124125
| `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 |
125126
| `leetcode.enableStatusBar` | Specify whether the LeetCode status bar will be shown or not. | `true` |
126127
| **(Deprecated)** `leetcode.enableShortcuts` | Specify whether the submit and test shortcuts in editor or not. | `true` |

docs/README_zh-CN.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
- 直接点击题目或者在 `LeetCode Explorer`**右键**题目并选择 `Preview Problem` 可查看题目描述
7474
- 选择 `Show Problem` 可直接进行答题。
7575

76-
> 注意:若当前 VS Code 没有已打开的文件夹,则生成的题目文件会存储于 **$HOME/.leetcode/** 目录下
76+
> 注意:你可以通过更新配置项 `leetcode.workspaceFolder` 来指定保存题目文件所用的工作区路径。默认工作区路径为:**$HOME/.leetcode/**
7777
7878
> 注意:你可以通过更新配置项 `leetcode.showCommentDescription` 来指定是否要在注释中包含题目描述。
7979
@@ -121,6 +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` |
124125
| `leetcode.outputFolder` | 指定保存文件时所用的相对文件夹路径。除了用户自定义路径外,也可以使用保留项,包括:<ul><li>`${tag}`: 根据题目的类别进行分类。<li>`${language}`: 根据题目的语言进行分类。</li><li>`${difficulty}`: 根据题目的难度进行分类。</li></ul>例如:`problem-${tag}-${difficulty}` | N/A |
125126
| `leetcode.enableStatusBar` | 指定是否在 VS Code 下方显示插件状态栏。 | `true` |
126127
| **(Deprecated)** `leetcode.enableShortcuts` | 指定是否在 VS Code 编辑文件下方显示提交和测试的快捷按钮。 | `true` |

package.json

+6
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,12 @@
310310
],
311311
"description": "Endpoint of the user account."
312312
},
313+
"leetcode.workspaceFolder": {
314+
"type": "string",
315+
"scope": "application",
316+
"description": "The path of the workspace folder to store the problem files.",
317+
"default": "${home}/.leetcode"
318+
},
313319
"leetcode.outputFolder": {
314320
"type": "string",
315321
"scope": "application",

src/commands/show.ts

+4
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ async function showProblemInternal(node: IProblem): Promise<void> {
128128

129129
const leetCodeConfig: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("leetcode");
130130
let outDir: string = await selectWorkspaceFolder();
131+
if (!outDir) {
132+
return;
133+
}
134+
131135
let relativePath: string = (leetCodeConfig.get<string>("outputFolder", "")).trim();
132136
if (relativePath) {
133137
relativePath = await resolveRelativePath(relativePath, node, language);

src/utils/settingUtils.ts

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

4+
import * as os from "os";
45
import { workspace, WorkspaceConfiguration } from "vscode";
56

67
export function getWorkspaceConfiguration(): WorkspaceConfiguration {
@@ -11,6 +12,11 @@ export function shouldHideSolvedProblem(): boolean {
1112
return getWorkspaceConfiguration().get<boolean>("hideSolved", false);
1213
}
1314

15+
export function getWorkspaceFolder(): string {
16+
const rawWorkspaceFolder: string = getWorkspaceConfiguration().get<string>("workspaceFolder", "${home}/.leetcode");
17+
return rawWorkspaceFolder.replace(/\${home}/i, os.homedir());
18+
}
19+
1420
export function getEditorShortcuts(): string[] {
1521
return getWorkspaceConfiguration().get<string[]>("editor.shortcuts", ["submit", "test"]);
1622
}

src/utils/workspaceUtils.ts

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

4-
import * as os from "os";
54
import * as path from "path";
65
import * as vscode from "vscode";
6+
import { getWorkspaceFolder } from "./settingUtils";
77
import * as wsl from "./wslUtils";
88

99
export async function selectWorkspaceFolder(): Promise<string> {
10-
let folder: vscode.WorkspaceFolder | undefined;
11-
if (vscode.workspace.workspaceFolders && vscode.workspace.workspaceFolders.length > 0) {
12-
if (vscode.workspace.workspaceFolders.length > 1) {
13-
folder = await vscode.window.showWorkspaceFolderPick({
14-
placeHolder: "Select the working directory you wish to use",
15-
});
16-
} else {
17-
folder = vscode.workspace.workspaceFolders[0];
10+
const workspaceFolderSetting: string = getWorkspaceFolder();
11+
const workspaceFolders: vscode.WorkspaceFolder[] = vscode.workspace.workspaceFolders || [];
12+
let needAsk: boolean = true;
13+
for (const folder of workspaceFolders) {
14+
if (isSubFolder(folder.uri.fsPath, workspaceFolderSetting)) {
15+
needAsk = false;
1816
}
1917
}
2018

21-
const workFolder: string = folder ? folder.uri.fsPath : path.join(os.homedir(), ".leetcode");
19+
if (needAsk) {
20+
const choice: string | undefined = await vscode.window.showQuickPick(
21+
[
22+
OpenOption.openInCurrentWindow,
23+
OpenOption.openInNewWindow,
24+
OpenOption.addToWorkspace,
25+
],
26+
{ placeHolder: "Select how you would like to open your workspace folder" },
27+
);
2228

23-
return wsl.useWsl() ? wsl.toWslPath(workFolder) : workFolder;
29+
switch (choice) {
30+
case OpenOption.openInCurrentWindow:
31+
await vscode.commands.executeCommand("vscode.openFolder", vscode.Uri.file(workspaceFolderSetting), false);
32+
return "";
33+
case OpenOption.openInNewWindow:
34+
await vscode.commands.executeCommand("vscode.openFolder", vscode.Uri.file(workspaceFolderSetting), true);
35+
return "";
36+
case OpenOption.addToWorkspace:
37+
vscode.workspace.updateWorkspaceFolders(workspaceFolders.length, 0, { uri: vscode.Uri.file(workspaceFolderSetting) });
38+
break;
39+
default:
40+
return "";
41+
}
42+
}
43+
44+
return wsl.useWsl() ? wsl.toWslPath(workspaceFolderSetting) : workspaceFolderSetting;
2445
}
2546

2647
export async function getActiveFilePath(uri?: vscode.Uri): Promise<string | undefined> {
@@ -40,3 +61,14 @@ export async function getActiveFilePath(uri?: vscode.Uri): Promise<string | unde
4061
}
4162
return wsl.useWsl() ? wsl.toWslPath(textEditor.document.uri.fsPath) : textEditor.document.uri.fsPath;
4263
}
64+
65+
function isSubFolder(from: string, to: string): boolean {
66+
const relative: string = path.relative(from, to);
67+
return !!relative && !relative.startsWith("..") && !path.isAbsolute(relative);
68+
}
69+
70+
enum OpenOption {
71+
openInCurrentWindow = "Open in current window",
72+
openInNewWindow = "Open in new window",
73+
addToWorkspace = "Add to workspace",
74+
}

0 commit comments

Comments
 (0)