From e1f3206756c1909c36a3832bec8f010e4e18bf8e Mon Sep 17 00:00:00 2001 From: Sheng Chen Date: Fri, 12 Jul 2019 15:16:12 +0800 Subject: [PATCH] feat: Can select folder to save the LeetCode files (#365) --- README.md | 2 +- docs/README_zh-CN.md | 2 +- package.json | 2 +- src/utils/settingUtils.ts | 4 +-- src/utils/uiUtils.ts | 12 +++++++++ src/utils/workspaceUtils.ts | 50 +++++++++++++++++++++++++++++++++++-- 6 files changed, 64 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ce36142a..95067331 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ | `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` | | `leetcode.useWsl` | Specify whether to use WSL or not | `false` | | `leetcode.endpoint` | Specify the active endpoint. Supported endpoints are: `leetcode`, `leetcode-cn` | `leetcode` | -| `leetcode.workspaceFolder` | Specify the path of the workspace folder to store the problem files. | `${home}/.leetcode` | +| `leetcode.workspaceFolder` | Specify the path of the workspace folder to store the problem files. | `""` | | `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: For example: `problem-${tag}-${difficulty}` | N/A | | `leetcode.enableStatusBar` | Specify whether the LeetCode status bar will be shown or not. | `true` | | **(Deprecated)** `leetcode.enableShortcuts` | Specify whether the submit and test shortcuts in editor or not. | `true` | diff --git a/docs/README_zh-CN.md b/docs/README_zh-CN.md index be328359..c23ea861 100644 --- a/docs/README_zh-CN.md +++ b/docs/README_zh-CN.md @@ -121,7 +121,7 @@ | `leetcode.defaultLanguage` | 指定答题时使用的默认语言,可选语言有:`bash`, `c`, `cpp`, `csharp`, `golang`, `java`, `javascript`, `kotlin`, `mysql`, `php`, `python`,`python3`,`ruby`, `rust`, `scala`,`swift` | `N/A` | | `leetcode.useWsl` | 指定是否启用 WSL | `false` | | `leetcode.endpoint` | 指定使用的终端,可用终端有:`leetcode`, `leetcode-cn` | `leetcode` | -| `leetcode.workspaceFolder` | 指定保存文件的工作区目录 | `${home}/.leetcode` | +| `leetcode.workspaceFolder` | 指定保存文件的工作区目录 | `""` | | `leetcode.outputFolder` | 指定保存文件时所用的相对文件夹路径。除了用户自定义路径外,也可以使用保留项,包括:例如:`problem-${tag}-${difficulty}` | N/A | | `leetcode.enableStatusBar` | 指定是否在 VS Code 下方显示插件状态栏。 | `true` | | **(Deprecated)** `leetcode.enableShortcuts` | 指定是否在 VS Code 编辑文件下方显示提交和测试的快捷按钮。 | `true` | diff --git a/package.json b/package.json index 66450123..bb04635b 100644 --- a/package.json +++ b/package.json @@ -314,7 +314,7 @@ "type": "string", "scope": "application", "description": "The path of the workspace folder to store the problem files.", - "default": "${home}/.leetcode" + "default": "" }, "leetcode.outputFolder": { "type": "string", diff --git a/src/utils/settingUtils.ts b/src/utils/settingUtils.ts index b7cb5919..388f31b8 100644 --- a/src/utils/settingUtils.ts +++ b/src/utils/settingUtils.ts @@ -1,7 +1,6 @@ // Copyright (c) jdneo. All rights reserved. // Licensed under the MIT license. -import * as os from "os"; import { workspace, WorkspaceConfiguration } from "vscode"; export function getWorkspaceConfiguration(): WorkspaceConfiguration { @@ -13,8 +12,7 @@ export function shouldHideSolvedProblem(): boolean { } export function getWorkspaceFolder(): string { - const rawWorkspaceFolder: string = getWorkspaceConfiguration().get("workspaceFolder", "${home}/.leetcode"); - return rawWorkspaceFolder.replace(/\${home}/i, os.homedir()); + return getWorkspaceConfiguration().get("workspaceFolder", ""); } export function getEditorShortcuts(): string[] { diff --git a/src/utils/uiUtils.ts b/src/utils/uiUtils.ts index 1fec63e3..037b2371 100644 --- a/src/utils/uiUtils.ts +++ b/src/utils/uiUtils.ts @@ -92,6 +92,18 @@ export async function showFileSelectDialog(): Promise return await vscode.window.showOpenDialog(options); } +export async function showDirectorySelectDialog(): Promise { + const defaultUri: vscode.Uri | undefined = vscode.workspace.rootPath ? vscode.Uri.file(vscode.workspace.rootPath) : undefined; + const options: vscode.OpenDialogOptions = { + defaultUri, + canSelectFiles: false, + canSelectFolders: true, + canSelectMany: false, + openLabel: "Select", + }; + return await vscode.window.showOpenDialog(options); +} + export async function openUrl(url: string): Promise { vscode.commands.executeCommand("vscode.open", vscode.Uri.parse(url)); } diff --git a/src/utils/workspaceUtils.ts b/src/utils/workspaceUtils.ts index b27a3ddf..b77fc3c7 100644 --- a/src/utils/workspaceUtils.ts +++ b/src/utils/workspaceUtils.ts @@ -1,13 +1,23 @@ // Copyright (c) jdneo. All rights reserved. // Licensed under the MIT license. +import * as os from "os"; import * as path from "path"; import * as vscode from "vscode"; -import { getWorkspaceFolder } from "./settingUtils"; +import { IQuickItemEx } from "../shared"; +import { getWorkspaceConfiguration, getWorkspaceFolder } from "./settingUtils"; +import { showDirectorySelectDialog } from "./uiUtils"; import * as wsl from "./wslUtils"; export async function selectWorkspaceFolder(): Promise { - const workspaceFolderSetting: string = getWorkspaceFolder(); + let workspaceFolderSetting: string = getWorkspaceFolder(); + if (workspaceFolderSetting.trim() === "") { + workspaceFolderSetting = await determineLeetCodeFolder(); + if (workspaceFolderSetting === "") { + // User cancelled + return workspaceFolderSetting; + } + } const workspaceFolders: vscode.WorkspaceFolder[] = vscode.workspace.workspaceFolders || []; let needAsk: boolean = true; for (const folder of workspaceFolders) { @@ -70,6 +80,42 @@ function isSubFolder(from: string, to: string): boolean { return !relative.startsWith("..") && !path.isAbsolute(relative); } +async function determineLeetCodeFolder(): Promise { + let result: string; + const picks: Array> = []; + picks.push( + { + label: `Default location`, + detail: `${path.join(os.homedir(), ".leetcode")}`, + value: `${path.join(os.homedir(), ".leetcode")}`, + }, + { + label: "$(file-directory) Browse...", + value: ":browse", + }, + ); + const choice: IQuickItemEx | undefined = await vscode.window.showQuickPick( + picks, + { placeHolder: "Select where you would like to save your LeetCode files" }, + ); + if (!choice) { + result = ""; + } else if (choice.value === ":browse") { + const directory: vscode.Uri[] | undefined = await showDirectorySelectDialog(); + if (!directory || directory.length < 1) { + result = ""; + } else { + result = directory[0].fsPath; + } + } else { + result = choice.value; + } + + getWorkspaceConfiguration().update("workspaceFolder", result, vscode.ConfigurationTarget.Global); + + return result; +} + enum OpenOption { openInCurrentWindow = "Open in current window", openInNewWindow = "Open in new window",