From f8ee234d5df97e32293de3e87865458e71acdb8a Mon Sep 17 00:00:00 2001 From: Sheng Chen Date: Wed, 23 Sep 2020 16:36:53 +0800 Subject: [PATCH] feat: Add inline button for create new class (#331) --- package.json | 19 ++++++++++--- src/explorerCommands/new.ts | 56 ++++++++++++++++++++++++++++++++++--- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/package.json b/package.json index 278ef24b..0a2a2a5c 100644 --- a/package.json +++ b/package.json @@ -132,7 +132,8 @@ { "command": "java.view.package.newJavaClass", "title": "%contributes.commands.java.view.package.newJavaClass%", - "category": "Java" + "category": "Java", + "icon": "$(add)" }, { "command": "java.view.package.newPackage", @@ -248,9 +249,9 @@ ], "explorer/context": [ { - "command": "java.view.package.revealInProjectExplorer", - "when": "resourceExtname == .java && java:projectManagerActivated && java:serverMode == Standard", - "group": "java:project_10" + "command": "java.view.package.revealInProjectExplorer", + "when": "resourceExtname == .java && java:projectManagerActivated && java:serverMode == Standard", + "group": "java:project_10" } ], "view/title": [ @@ -321,6 +322,16 @@ "when": "view == javaProjectExplorer && viewItem =~ /java:(package|packageRoot)(?=.*?\\b\\+source\\b)(?=.*?\\b\\+uri\\b)/", "group": "new@10" }, + { + "command": "java.view.package.newJavaClass", + "when": "view == javaProjectExplorer && viewItem =~ /java:project(?=.*?\\b\\+java\\b)(?=.*?\\b\\+uri\\b)/", + "group": "inline@add_0" + }, + { + "command": "java.view.package.newJavaClass", + "when": "view == javaProjectExplorer && viewItem =~ /java:(package|packageRoot)(?=.*?\\b\\+source\\b)(?=.*?\\b\\+uri\\b)/", + "group": "inline@add_0" + }, { "command": "java.view.package.newPackage", "when": "view == javaProjectExplorer && viewItem =~ /java:(package|packageRoot)(?=.*?\\b\\+source\\b)(?=.*?\\b\\+uri\\b)/", diff --git a/src/explorerCommands/new.ts b/src/explorerCommands/new.ts index 0a28f886..7032b21a 100644 --- a/src/explorerCommands/new.ts +++ b/src/explorerCommands/new.ts @@ -3,13 +3,17 @@ import * as fse from "fs-extra"; import * as path from "path"; -import { Uri, window, workspace, WorkspaceEdit } from "vscode"; +import { QuickPickItem, Uri, window, workspace, WorkspaceEdit } from "vscode"; import { NodeKind } from "../java/nodeData"; import { isJavaIdentifier, isKeyword } from "../utility"; import { DataNode } from "../views/dataNode"; export async function newJavaClass(node: DataNode): Promise { - const packageFsPath: string = Uri.parse(node.uri).fsPath; + const packageFsPath: string = await getPackageFsPath(node); + if (!packageFsPath) { + return; + } + const className: string | undefined = await window.showInputBox({ placeHolder: "Input the class name", ignoreFocusOut: true, @@ -39,6 +43,42 @@ export async function newJavaClass(node: DataNode): Promise { workspace.applyEdit(workspaceEdit); } +async function getPackageFsPath(node: DataNode): Promise { + if (node.nodeData.kind === NodeKind.Project) { + const childrenNodes: DataNode[] = await node.getChildren() as DataNode[]; + const packageRoots: any[] = childrenNodes.filter((child) => { + return child.nodeData.kind === NodeKind.PackageRoot; + }); + if (packageRoots.length < 1) { + // This might happen for an invisible project with "_" as its root + const packageNode: DataNode = childrenNodes.find((child) => { + return child.nodeData.kind === NodeKind.Package; + }); + if (packageNode) { + return getPackageRootPath(Uri.parse(packageNode.uri).fsPath, packageNode.name); + } + return ""; + } else if (packageRoots.length === 1) { + return Uri.parse(packageRoots[0].uri).fsPath; + } else { + const options: ISourceRootPickItem[] = packageRoots.map((root) => { + return { + label: root.name, + fsPath: Uri.parse(root.uri).fsPath, + }; + }); + const choice: ISourceRootPickItem | undefined = await window.showQuickPick(options, { + placeHolder: "Choose a source folder", + ignoreFocusOut: true, + }, + ); + return choice ? choice.fsPath : ""; + } + } + + return Uri.parse(node.uri).fsPath; +} + function getNewFilePath(basePath: string, className: string): string { if (className.endsWith(".java")) { className = className.substr(0, className.length - ".java".length); @@ -54,8 +94,7 @@ export async function newPackage(node: DataNode): Promise { packageRootPath = Uri.parse(node.uri).fsPath; } else if (node.nodeData.kind === NodeKind.Package) { defaultValue = node.nodeData.name + "."; - const numberOfSegment: number = node.nodeData.name.split(".").length; - packageRootPath = path.join(Uri.parse(node.uri).fsPath, ...Array(numberOfSegment).fill("..")); + packageRootPath = getPackageRootPath(Uri.parse(node.uri).fsPath, node.nodeData.name); } else { return; } @@ -86,6 +125,11 @@ export async function newPackage(node: DataNode): Promise { await fse.ensureDir(getNewPackagePath(packageRootPath, packageName)); } +function getPackageRootPath(packageFsPath: string, packageName: string): string { + const numberOfSegment: number = packageName.split(".").length; + return path.join(packageFsPath, ...Array(numberOfSegment).fill("..")); +} + function getNewPackagePath(packageRootPath: string, packageName: string): string { return path.join(packageRootPath, ...packageName.split(".")); } @@ -107,3 +151,7 @@ function checkJavaQualifiedName(value: string): string { return ""; } + +interface ISourceRootPickItem extends QuickPickItem { + fsPath: string; +}