From 5e06afc0d02318aa668520433aa9f8e1d334a02f Mon Sep 17 00:00:00 2001 From: Steffen Leistner Date: Fri, 6 Nov 2020 17:33:14 +0100 Subject: [PATCH] feat(NewFileCommand): add support for brace expansion --- package.json | 5 ++- src/command/NewFileCommand.ts | 11 +++++- src/command/NewFolderCommand.ts | 9 +++-- src/controller/BaseFileController.ts | 6 +-- src/controller/FileController.ts | 2 +- src/controller/NewFileController.ts | 11 ++++-- yarn.lock | 56 +++++++--------------------- 7 files changed, 44 insertions(+), 56 deletions(-) diff --git a/package.json b/package.json index 60aa2acb..b9995869 100644 --- a/package.json +++ b/package.json @@ -189,6 +189,7 @@ "@semantic-release/npm": "7.0.6", "@types/bluebird": "3.5.33", "@types/bluebird-retry": "0.11.4", + "@types/brace-expansion": "^1.1.0", "@types/chai": "4.2.14", "@types/mocha": "8.0.3", "@types/node": "12.19.3", @@ -209,7 +210,9 @@ "typescript": "4.0.5", "vscode-test": "1.4.1" }, - "dependencies": {}, + "dependencies": { + "brace-expansion": "^2.0.0" + }, "husky": { "hooks": { "pre-commit": "yarn run lint && yarm run test" diff --git a/src/command/NewFileCommand.ts b/src/command/NewFileCommand.ts index bbdd56bb..02bd0672 100644 --- a/src/command/NewFileCommand.ts +++ b/src/command/NewFileCommand.ts @@ -5,7 +5,14 @@ export class NewFileCommand extends BaseCommand { public async execute(): Promise { const relativeToRoot = this.options?.relativeToRoot ?? false; const dialogOptions = { prompt: "File Name", relativeToRoot }; - const fileItem = await this.controller.showDialog(dialogOptions); - await this.executeController(fileItem, { openFileInEditor: true }); + const fileItems = await this.controller.showDialog(dialogOptions); + + if (fileItems) { + const executions = [...fileItems].map(async (fileItem) => { + const result = await this.controller.execute({ fileItem }); + await this.controller.openFileInEditor(result); + }); + await Promise.all(executions); + } } } diff --git a/src/command/NewFolderCommand.ts b/src/command/NewFolderCommand.ts index b53d42a8..3ce4ab78 100644 --- a/src/command/NewFolderCommand.ts +++ b/src/command/NewFolderCommand.ts @@ -4,10 +4,13 @@ export class NewFolderCommand extends NewFileCommand { public async execute(): Promise { const relativeToRoot = this.options?.relativeToRoot ?? false; const dialogOptions = { prompt: "Folder Name", relativeToRoot }; - const fileItem = await this.controller.showDialog(dialogOptions); + const fileItems = await this.controller.showDialog(dialogOptions); - if (fileItem) { - await this.controller.execute({ fileItem, isDir: true }); + if (fileItems) { + const executions = [...fileItems].map(async (fileItem) => { + await this.controller.execute({ fileItem, isDir: true }); + }); + await Promise.all(executions); } } } diff --git a/src/controller/BaseFileController.ts b/src/controller/BaseFileController.ts index bb050ff3..200f8da0 100644 --- a/src/controller/BaseFileController.ts +++ b/src/controller/BaseFileController.ts @@ -1,4 +1,4 @@ -import { commands, env, ExtensionContext, TextEditor, ViewColumn, window, workspace } from "vscode"; +import { commands, env, ExtensionContext, TextEditor, window, workspace } from "vscode"; import { FileItem } from "../FileItem"; import { Cache } from "../lib/Cache"; import { DialogOptions, ExecuteOptions, FileController, GetSourcePathOptions } from "./FileController"; @@ -6,7 +6,7 @@ import { DialogOptions, ExecuteOptions, FileController, GetSourcePathOptions } f export abstract class BaseFileController implements FileController { constructor(protected context: ExtensionContext) {} - public abstract async showDialog(options?: DialogOptions): Promise; + public abstract async showDialog(options?: DialogOptions): Promise; public abstract async execute(options: ExecuteOptions): Promise; @@ -20,7 +20,7 @@ export abstract class BaseFileController implements FileController { throw new Error("Could not open file!"); } - const editor = await window.showTextDocument(textDocument, ViewColumn.Active); + const editor = await window.showTextDocument(textDocument); if (!editor) { throw new Error("Could not show document!"); } diff --git a/src/controller/FileController.ts b/src/controller/FileController.ts index 1aa079a7..b382229a 100644 --- a/src/controller/FileController.ts +++ b/src/controller/FileController.ts @@ -15,7 +15,7 @@ export interface GetSourcePathOptions { } export interface FileController { - showDialog(options?: DialogOptions): Promise; + showDialog(options?: DialogOptions): Promise; execute(options: ExecuteOptions): Promise; openFileInEditor(fileItem: FileItem): Promise; closeCurrentFileEditor(): Promise; diff --git a/src/controller/NewFileController.ts b/src/controller/NewFileController.ts index 4451f11a..72af47d3 100644 --- a/src/controller/NewFileController.ts +++ b/src/controller/NewFileController.ts @@ -5,6 +5,7 @@ import { getConfiguration } from "../lib/config"; import { BaseFileController } from "./BaseFileController"; import { DialogOptions, ExecuteOptions, GetSourcePathOptions } from "./FileController"; import { TypeAheadController } from "./TypeAheadController"; +import expand from "brace-expansion"; export interface NewFileDialogOptions extends DialogOptions { relativeToRoot?: boolean; @@ -15,7 +16,7 @@ export interface NewFileExecuteOptions extends ExecuteOptions { } export class NewFileController extends BaseFileController { - public async showDialog(options: NewFileDialogOptions): Promise { + public async showDialog(options: NewFileDialogOptions): Promise { const { prompt, relativeToRoot = false } = options; const sourcePath = await this.getSourcePath({ relativeToRoot }); const value: string = path.join(sourcePath, path.sep); @@ -27,9 +28,11 @@ export class NewFileController extends BaseFileController { }); if (targetPath) { - const isDir = targetPath.endsWith(path.sep); - const realPath = path.resolve(sourcePath, targetPath); - return new FileItem(sourcePath, realPath, isDir); + return expand(targetPath).map((filePath) => { + const realPath = path.resolve(sourcePath, filePath); + const isDir = filePath.endsWith(path.sep); + return new FileItem(sourcePath, realPath, isDir); + }); } } diff --git a/yarn.lock b/yarn.lock index 9db60614..a6f3db62 100644 --- a/yarn.lock +++ b/yarn.lock @@ -358,6 +358,11 @@ resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.33.tgz#d79c020f283bd50bd76101d7d300313c107325fc" integrity sha512-ndEo1xvnYeHxm7I/5sF6tBvnsA4Tdi3zj1keRKRs12SP+2ye2A27NDJ1B6PqkfMbGAcT+mqQVqbZRIrhfOp5PQ== +"@types/brace-expansion@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@types/brace-expansion/-/brace-expansion-1.1.0.tgz#fbce69132b7277e35e4d4bfc13a69c0d1ab6ebf8" + integrity sha512-SaU/Kgp6z40CiF9JxlsrSrBEa+8YIry9IiCPhhYSNekeEhIAkY7iyu9aZ+5dSQIdo7mf86MUVvxWYm5GAzB/0g== + "@types/chai@*": version "4.2.0" resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.0.tgz#2478260021408dec32c123a7cad3414beb811a07" @@ -906,6 +911,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.0.tgz#3b53b490c803c23a6a5d6c9c8b309879c37c7f98" + integrity sha512-A4GHY1GpcTnp+Elcwp1CbKHY6ZQwwVR7QdjZk4fPetEh7oNBfICu+eLvvVvTEMHgC+SGn+XiLAgGo0MnPPBGOg== + dependencies: + balanced-match "^1.0.0" + braces@^3.0.1, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" @@ -1569,7 +1581,7 @@ debug@^4.0.0: dependencies: ms "^2.1.1" -debuglog@*, debuglog@^1.0.1: +debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= @@ -2881,7 +2893,7 @@ import-lazy@^2.1.0: resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= -imurmurhash@*, imurmurhash@^0.1.4: +imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= @@ -3512,11 +3524,6 @@ lockfile@^1.0.4: dependencies: signal-exit "^3.0.2" -lodash._baseindexof@*: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c" - integrity sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw= - lodash._baseuniq@~4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" @@ -3525,33 +3532,11 @@ lodash._baseuniq@~4.6.0: lodash._createset "~4.0.0" lodash._root "~3.0.0" -lodash._bindcallback@*: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" - integrity sha1-5THCdkTPi1epnhftlbNcdIeJOS4= - -lodash._cacheindexof@*: - version "3.0.2" - resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92" - integrity sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI= - -lodash._createcache@*: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093" - integrity sha1-VtagZAF2JeeevKa4AY4XRAvc8JM= - dependencies: - lodash._getnative "^3.0.0" - lodash._createset@~4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY= -lodash._getnative@*, lodash._getnative@^3.0.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" - integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= - lodash._root@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" @@ -3592,11 +3577,6 @@ lodash.isstring@^4.0.1: resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= -lodash.restparam@*: - version "3.6.1" - resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" - integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU= - lodash.toarray@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" @@ -4320,7 +4300,6 @@ npm@^6.13.0: cmd-shim "^3.0.3" columnify "~1.5.4" config-chain "^1.1.12" - debuglog "*" detect-indent "~5.0.0" detect-newline "^2.1.0" dezalgo "~1.0.3" @@ -4335,7 +4314,6 @@ npm@^6.13.0: has-unicode "~2.0.1" hosted-git-info "^2.8.8" iferr "^1.0.2" - imurmurhash "*" infer-owner "^1.0.4" inflight "~1.0.6" inherits "^2.0.4" @@ -4354,14 +4332,8 @@ npm@^6.13.0: libnpx "^10.2.4" lock-verify "^2.1.0" lockfile "^1.0.4" - lodash._baseindexof "*" lodash._baseuniq "~4.6.0" - lodash._bindcallback "*" - lodash._cacheindexof "*" - lodash._createcache "*" - lodash._getnative "*" lodash.clonedeep "~4.5.0" - lodash.restparam "*" lodash.union "~4.6.0" lodash.uniq "~4.5.0" lodash.without "~4.4.0"