You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@netbeans.apache.org by en...@apache.org on 2021/12/21 11:12:02 UTC

[netbeans] branch master updated: Run Configuration UI for the Explorer view (#3378)

This is an automated email from the ASF dual-hosted git repository.

entl pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/netbeans.git


The following commit(s) were added to refs/heads/master by this push:
     new a97bb92  Run Configuration UI for the Explorer view (#3378)
a97bb92 is described below

commit a97bb92e9d6bb770a4bf84ef5e6d2006264fdc5a
Author: Jiri Sedlacek <ji...@oracle.com>
AuthorDate: Tue Dec 21 12:11:49 2021 +0100

    Run Configuration UI for the Explorer view (#3378)
    
    Run Configuration UI for the Explorer view
---
 java/java.lsp.server/vscode/package.json           |  40 ++++
 java/java.lsp.server/vscode/src/extension.ts       |  13 ++
 .../java.lsp.server/vscode/src/runConfiguration.ts | 218 +++++++++++++++++++++
 3 files changed, 271 insertions(+)

diff --git a/java/java.lsp.server/vscode/package.json b/java/java.lsp.server/vscode/package.json
index 5561d99..c86bfd8 100644
--- a/java/java.lsp.server/vscode/package.json
+++ b/java/java.lsp.server/vscode/package.json
@@ -71,6 +71,12 @@
 					"id": "database.connections",
 					"name": "Databases",
 					"when": "nbJavaLSReady"
+				},
+				{
+					"id": "run-config",
+					"name": "Run Configuration",
+					"contextualTitle": "Run Configuration",
+					"when": "runConfigurationInitialized"
 				}
 			]
 		},
@@ -150,6 +156,26 @@
 					"description": "Members count to use a static star-import",
 					"default": 999,
 					"minimum": 1
+				},
+				"java8+.runConfig.arguments": {
+					"type": "string",
+					"default": "",
+					"description": "Arguments"
+				},
+				"java8+.runConfig.vmOptions": {
+					"type": "string",
+					"default": "",
+					"description": "VM options"
+				},
+				"java8+.runConfig.env": {
+					"type": "string",
+					"default": "",
+					"description": "Environment variables"
+				},
+				"java8+.runConfig.cwd": {
+					"type": "string",
+					"default": "",
+					"description": "Working directory"
 				}
 			}
 		},
@@ -463,6 +489,11 @@
 			{
 				"command": "java.local.db.set.preferred.connection",
 				"title": "Make Default Connection"
+			},
+			{
+				"command": "java.workspace.configureRunSettings",
+				"title": "Edit",
+				"icon": "$(edit)"
 			}
 		],
 		"keybindings": [
@@ -538,6 +569,10 @@
 				{
 					"command": "java.local.db.set.preferred.connection",
 					"when": "false"
+				},
+				{
+					"command": "java.workspace.configureRunSettings",
+					"when": "false"
 				}
 			],
 			"view/title": [
@@ -614,6 +649,11 @@
 				{
 					"command": "java.local.db.set.preferred.connection",
 					"when": "viewItem =~ /class:ddl.DBConnection/"
+				},
+				{
+					"command": "java.workspace.configureRunSettings",
+					"when": "view == run-config && viewItem == configureRunSettings",
+					"group": "inline@1"
 				}
 			]
 		}
diff --git a/java/java.lsp.server/vscode/src/extension.ts b/java/java.lsp.server/vscode/src/extension.ts
index 8cd061e..9594f53 100644
--- a/java/java.lsp.server/vscode/src/extension.ts
+++ b/java/java.lsp.server/vscode/src/extension.ts
@@ -51,6 +51,7 @@ import { asRanges, StatusMessageRequest, ShowStatusMessageParams, QuickPickReque
 } from './protocol';
 import * as launchConfigurations from './launchConfigurations';
 import { createTreeViewService, TreeViewService, TreeItemDecorator, Visualizer, CustomizableTreeDataProvider } from './explorer';
+import { initializeRunConfiguration, runConfigurationProvider, runConfigurationNodeProvider, configureRunSettings } from './runConfiguration';
 import { TLSSocket } from 'tls';
 
 const API_VERSION : string = "1.0";
@@ -320,6 +321,18 @@ export function activate(context: ExtensionContext): VSNetBeansAPI {
     let sourceForContentProvider = new NetBeansSourceForContentProvider();
     context.subscriptions.push(vscode.workspace.registerTextDocumentContentProvider('sourceFor', sourceForContentProvider));
 
+    // initialize Run Configuration
+    initializeRunConfiguration().then(initialized => {
+		if (initialized) {
+			context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('java8+', runConfigurationProvider));
+			context.subscriptions.push(vscode.window.registerTreeDataProvider('run-config', runConfigurationNodeProvider));
+			context.subscriptions.push(vscode.commands.registerCommand('java.workspace.configureRunSettings', (...params: any[]) => {
+				configureRunSettings(context, params);
+			}));
+			vscode.commands.executeCommand('setContext', 'runConfigurationInitialized', true);
+		}
+	});
+
     // register commands
     context.subscriptions.push(commands.registerCommand('java.workspace.new', async (ctx) => {
         let c : LanguageClient = await client;
diff --git a/java/java.lsp.server/vscode/src/runConfiguration.ts b/java/java.lsp.server/vscode/src/runConfiguration.ts
new file mode 100644
index 0000000..be6c37e
--- /dev/null
+++ b/java/java.lsp.server/vscode/src/runConfiguration.ts
@@ -0,0 +1,218 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import * as vscode from 'vscode';
+import { homedir } from 'os';
+
+export async function initializeRunConfiguration(): Promise<boolean> {
+	const java = await vscode.workspace.findFiles('**/*.java', '**/node_modules/**', 1);
+	if (java?.length > 0) {
+		const maven = await vscode.workspace.findFiles('pom.xml', '**/node_modules/**', 1);
+		if (maven?.length > 0) {
+			return true;
+		}
+		const gradle = await vscode.workspace.findFiles('build.gradle', '**/node_modules/**', 1);
+		if (gradle?.length > 0) {
+			return true;
+		}
+	}
+	return false;
+}
+
+class RunConfigurationProvider implements vscode.DebugConfigurationProvider {
+
+    resolveDebugConfiguration(_folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, _token?: vscode.CancellationToken): vscode.ProviderResult<vscode.DebugConfiguration> {
+		return new Promise<vscode.DebugConfiguration>(resolve => {
+			resolve(config);
+		});
+	}
+
+	resolveDebugConfigurationWithSubstitutedVariables?(_folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration, _token?: vscode.CancellationToken): vscode.ProviderResult<vscode.DebugConfiguration> {
+        return new Promise<vscode.DebugConfiguration>(resolve => {
+			const args = argumentsNode.getValue();
+			if (args) {
+				if (!config.args) {
+					config.args = args;
+				} else {
+					config.args = `${config.args} ${args}`;
+				}
+			}
+
+			const vmArgs = vmOptionsNode.getValue();
+			if (vmArgs) {
+				if (!config.vmArgs) {
+					config.vmArgs = vmArgs;
+				} else {
+					config.vmArgs = `${config.vmArgs} ${vmArgs}`;
+				}
+			}
+
+			const env = environmentVariablesNode.getValue();
+			if (env) {
+				const envs = env.split(',');
+				if (!config.env) {
+					config.env = {};
+				}
+				for (let val of envs) {
+					const vals = val.trim().split('=');
+					config.env[vals[0]] = vals[1];
+				}
+			}
+
+			const cwd = workingDirectoryNode.getValue();
+			if (cwd) {
+				config.cwd = cwd;
+			}
+			
+			resolve(config);
+		});
+	}
+
+}
+export const runConfigurationProvider = new RunConfigurationProvider();
+
+class RunConfigurationNodeProvider implements vscode.TreeDataProvider<vscode.TreeItem> {
+
+	private _onDidChangeTreeData: vscode.EventEmitter<vscode.TreeItem | undefined | null> = new vscode.EventEmitter<vscode.TreeItem | undefined | null>();
+	readonly onDidChangeTreeData: vscode.Event<vscode.TreeItem | undefined | null> = this._onDidChangeTreeData.event;
+
+	refresh(): void {
+		this._onDidChangeTreeData.fire(undefined);
+	}
+
+	getTreeItem(element: vscode.TreeItem): vscode.TreeItem {
+		return element;
+	}
+
+	getChildren(element?: vscode.TreeItem): vscode.ProviderResult<vscode.TreeItem[]> {
+        if (!element) {
+            return [ argumentsNode, vmOptionsNode, environmentVariablesNode, workingDirectoryNode ];
+        }
+        return [];
+	}
+
+}
+export const runConfigurationNodeProvider = new RunConfigurationNodeProvider();
+
+class RunConfigurationNode extends vscode.TreeItem {
+
+	prompt: string;
+	hint: string;
+	value: string | undefined;
+
+	settingsKey: string;
+
+    constructor(label: string, prompt: string, hint: string, settingsKey: string) {
+        super(label);
+        this.contextValue = 'configureRunSettings';
+        this.collapsibleState = vscode.TreeItemCollapsibleState.None;
+
+		this.prompt = prompt;
+		this.hint = hint;
+
+		this.settingsKey = settingsKey;
+		
+		this.value = this.getConfig().get(this.settingsKey);
+		this.updateNode();
+    }
+
+	public configure(_context: vscode.ExtensionContext) {
+		vscode.window.showInputBox(
+			{
+				prompt: this.prompt,
+				value: this.value,
+				placeHolder: this.hint,
+				ignoreFocusOut: true
+			}
+		).then(async val => {
+			if (val !== undefined) {
+				const value = val.toString().trim();
+				this.setValue(value ? value : undefined);
+			}
+		});
+	}
+
+	public getValue(): string | undefined {
+		return this.value;
+	}
+
+	setValue(value: string | undefined) {
+		this.value = value;
+		this.getConfig().update(this.settingsKey, this.value, false);
+		this.updateNode();
+        runConfigurationNodeProvider.refresh();
+	}
+
+	updateNode() {
+		this.description = this.value ? this.value : '<default>';
+        this.tooltip = `${this.label} ${this.description}`;
+	}
+
+	getConfig(): vscode.WorkspaceConfiguration {
+		return vscode.workspace.getConfiguration('java8+.runConfig');
+	}
+
+}
+
+class ArgumentsNode extends RunConfigurationNode {
+
+	constructor() {
+        super('Arguments:', 'Customize arguments', 'Example: foo bar', 'arguments');
+    }
+
+}
+const argumentsNode = new ArgumentsNode();
+
+class VMOptionsNode extends RunConfigurationNode {
+
+	constructor() {
+        super('VM Options:', 'Customize VM options', 'Example: -Xmx512m -Xms256m', 'vmOptions');
+    }
+
+}
+const vmOptionsNode = new VMOptionsNode();
+
+class EnvironmentVariablesNode extends RunConfigurationNode {
+
+	constructor() {
+        super('Environment:', 'Customize evironment variables', 'Example: var1=one, varTwo=2', 'env');
+    }
+
+}
+const environmentVariablesNode = new EnvironmentVariablesNode();
+
+class WorkingDirectoryNode extends RunConfigurationNode {
+
+	constructor() {
+        super('Working Dir:', 'Customize working directory', WorkingDirectoryNode.getExample(), 'cwd');
+    }
+
+	static getExample(): string {
+		const dir = homedir();
+		return `Example: ${dir}`;
+	}
+
+}
+const workingDirectoryNode = new WorkingDirectoryNode();
+
+export function configureRunSettings(context: vscode.ExtensionContext, ...params: any[]) {
+    if (params[0][0]) {
+        (params[0][0] as RunConfigurationNode).configure(context);
+    }
+}

---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@netbeans.apache.org
For additional commands, e-mail: commits-help@netbeans.apache.org

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists