Skip to content

Commit

Permalink
feat: Support new file contribution
Browse files Browse the repository at this point in the history
  • Loading branch information
jdneo committed Aug 12, 2021
1 parent 4256fa6 commit 2c25fc0
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 31 deletions.
22 changes: 11 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 8 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"explorer"
],
"engines": {
"vscode": "^1.53.0"
"vscode": "^1.59.0"
},
"repository": {
"type": "git",
Expand All @@ -31,6 +31,7 @@
"onCommand:java.project.create",
"onCommand:java.view.package.exportJar",
"onCommand:java.view.package.revealInProjectExplorer",
"onCommand:java.view.package.newJavaClass",
"onView:javaProjectExplorer"
],
"license": "MIT",
Expand Down Expand Up @@ -257,6 +258,11 @@
}
],
"menus": {
"file/newFile": [
{
"command": "java.view.package.newJavaClass"
}
],
"commandPalette": [
{
"command": "java.view.package.exportJar",
Expand Down Expand Up @@ -310,10 +316,6 @@
"command": "java.project.refreshLibraries",
"when": "false"
},
{
"command": "java.view.package.newJavaClass",
"when": "false"
},
{
"command": "java.view.package.newPackage",
"when": "false"
Expand Down Expand Up @@ -595,7 +597,7 @@
"@types/mocha": "^8.2.1",
"@types/node": "^8.10.66",
"@types/semver": "^7.3.8",
"@types/vscode": "1.53.0",
"@types/vscode": "1.59.0",
"copy-webpack-plugin": "^6.4.1",
"glob": "^7.1.6",
"gulp": "^4.0.2",
Expand Down
5 changes: 5 additions & 0 deletions src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ export namespace Commands {
export const WORKBENCH_ACTION_FILES_OPENFOLDER = "workbench.action.files.openFolder";

export const WORKBENCH_ACTION_FILES_OPENFILEFOLDER = "workbench.action.files.openFileFolder";

/**
* Commands from JLS
*/
export const LIST_SOURCEPATHS = "java.project.listSourcePaths";
}

export function executeJavaLanguageServerCommand(...rest: any[]) {
Expand Down
83 changes: 74 additions & 9 deletions src/explorerCommands/new.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,29 @@

import * as fse from "fs-extra";
import * as path from "path";
import { QuickPickItem, Uri, window, workspace, WorkspaceEdit } from "vscode";
import { commands, languages, QuickPickItem, SnippetString, TextEditor, Uri, window, workspace, WorkspaceEdit, WorkspaceFolder } from "vscode";
import { Commands } from "../../extension.bundle";
import { NodeKind } from "../java/nodeData";
import { DataNode } from "../views/dataNode";
import { checkJavaQualifiedName } from "./utility";

export async function newJavaClass(node?: DataNode): Promise<void> {
if (!node?.uri || !canCreateClass(node)) {
return;
let packageFsPath: string | undefined;
if (!node) {
packageFsPath = await inferPackageFsPath();
} else {
if (!node?.uri || !canCreateClass(node)) {
return;
}

packageFsPath = await getPackageFsPath(node);
}

const packageFsPath: string = await getPackageFsPath(node);
if (!packageFsPath) {
if (packageFsPath === undefined) {
// User canceled
return;
} else if (packageFsPath.length === 0) {
return newUntiledJavaFile();
}

const className: string | undefined = await window.showInputBox({
Expand All @@ -27,7 +37,7 @@ export async function newJavaClass(node?: DataNode): Promise<void> {
return checkMessage;
}

if (await fse.pathExists(getNewFilePath(packageFsPath, value))) {
if (await fse.pathExists(getNewFilePath(packageFsPath!, value))) {
return "Class already exists.";
}

Expand All @@ -47,6 +57,48 @@ export async function newJavaClass(node?: DataNode): Promise<void> {
workspace.applyEdit(workspaceEdit);
}

async function newUntiledJavaFile(): Promise<void> {
await commands.executeCommand("workbench.action.files.newUntitledFile");
const textEditor: TextEditor | undefined = window.activeTextEditor;
if (!textEditor) {
return;
}
await languages.setTextDocumentLanguage(textEditor.document, "java");
const snippets: string[] = [];
snippets.push(`public \${1|class,interface,enum,abstract class,@interface|} \${2:Main} {`);
snippets.push(`\t\${0}`);
snippets.push("}");
snippets.push("");
textEditor.insertSnippet(new SnippetString(snippets.join("\n")));
}

async function inferPackageFsPath(): Promise<string> {
if (!window.activeTextEditor) {
return "";
}
const fileUri: Uri = window.activeTextEditor.document.uri;
const workspaceFolder: WorkspaceFolder | undefined = workspace.getWorkspaceFolder(fileUri);
if (!workspaceFolder) {
return "";
}

const filePath: string = window.activeTextEditor.document.uri.fsPath;
try {
const result = await commands.executeCommand<ListCommandResult>(Commands.EXECUTE_WORKSPACE_COMMAND, Commands.LIST_SOURCEPATHS);
if (result && result.data && result.data.length) {
for (const sourcePath of result.data) {
if (!path.relative(sourcePath.path, filePath).startsWith("..")) {
return path.dirname(window.activeTextEditor.document.uri.fsPath);
}
}
}
} catch (e) {
// do nothing
}

return "";
}

function canCreateClass(node: DataNode): boolean {
if (node.nodeData.kind === NodeKind.Project ||
node.nodeData.kind === NodeKind.PackageRoot ||
Expand All @@ -58,7 +110,7 @@ function canCreateClass(node: DataNode): boolean {
return false;
}

async function getPackageFsPath(node: DataNode): Promise<string> {
async function getPackageFsPath(node: DataNode): Promise<string | undefined> {
if (node.nodeData.kind === NodeKind.Project) {
const childrenNodes: DataNode[] = await node.getChildren() as DataNode[];
const packageRoots: any[] = childrenNodes.filter((child) => {
Expand Down Expand Up @@ -90,7 +142,7 @@ async function getPackageFsPath(node: DataNode): Promise<string> {
ignoreFocusOut: true,
},
);
return choice ? choice.fsPath : "";
return choice?.fsPath;
}
} else if (node.nodeData.kind === NodeKind.PrimaryType) {
return node.uri ? path.dirname(Uri.parse(node.uri).fsPath) : "";
Expand All @@ -116,7 +168,7 @@ export async function newPackage(node?: DataNode): Promise<void> {
const nodeKind = node.nodeData.kind;
if (nodeKind === NodeKind.Project) {
defaultValue = "";
packageRootPath = await getPackageFsPath(node);
packageRootPath = await getPackageFsPath(node) || "";
} else if (nodeKind === NodeKind.PackageRoot) {
defaultValue = "";
packageRootPath = Uri.parse(node.uri).fsPath;
Expand Down Expand Up @@ -175,3 +227,16 @@ function getNewPackagePath(packageRootPath: string, packageName: string): string
interface ISourceRootPickItem extends QuickPickItem {
fsPath: string;
}

interface ListCommandResult {
status: boolean;
message: string;
data?: SourcePath[];
}

interface SourcePath {
path: string;
displayPath: string;
projectName: string;
projectType: string;
}
6 changes: 1 addition & 5 deletions src/views/dependencyExplorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,7 @@ export class DependencyExplorer implements Disposable {
// register keybinding commands
context.subscriptions.push(
instrumentOperationAsVsCodeCommand(Commands.VIEW_PACKAGE_NEW_JAVA_CLASS, async (node?: DataNode) => {
let cmdNode = getCmdNode(this._dependencyViewer.selection, node);
if (!cmdNode) {
cmdNode = await this.promptForProjectNode();
}
newJavaClass(cmdNode);
newJavaClass(node);
}),
instrumentOperationAsVsCodeCommand(Commands.VIEW_PACKAGE_NEW_JAVA_PACKAGE, async (node?: DataNode) => {
let cmdNode = getCmdNode(this._dependencyViewer.selection, node);
Expand Down

0 comments on commit 2c25fc0

Please sign in to comment.