diff --git a/CHANGELOG.md b/CHANGELOG.md
index 717aefbb64758..b2a2a28ab3d55 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,10 +4,12 @@
- [Previous Changelogs](https://github.com/eclipse-theia/theia/tree/master/doc/changelogs/)
-## v1.27.0 - 6/30/2022
+
+## v1.27.0 - Unreleased
[Breaking Changes:](#breaking_changes_1.27.0)
+- [plugin-dev] moved and renamed interface from: `@theia/debug/lib/browser/debug-contribution/DebugPluginConfiguration` to: `plugin-dev/src/common/PluginDebugConfiguration` [#11224](https://github.com/eclipse-theia/theia/pull/11224)
- [core] Refactored the core messaging API. Replaced `vscode-ws-jsonrpc` with a custom RPC protocol that is better suited for handling binary data and enables message tunneling.
This impacts all main concepts of the messaging API. The API no longer exposes a `Connection` object and uses a generic `Channel` implementation instead.
- Replaces usage of `vscode-json-rpc`'s `Connection` with the new generic `Channel`. Affects `AbstractConnectionProvider`, `MessagingService`, `IPCConnectionProvider`, `ElectronMessagingService`
diff --git a/doc/Developing.md b/doc/Developing.md
index effa760e0daed..394fbaf7ca39b 100644
--- a/doc/Developing.md
+++ b/doc/Developing.md
@@ -515,7 +515,7 @@ etc.) by opening `packages//coverage/index.html`.
- If you need to install `windows-build-tools`, see [`Installing Windows Build Tools`](#installing-windows-build-tools).
- If you run into problems with installing the required build tools, the `node-gyp` documentation offers a useful [guide](https://github.com/nodejs/node-gyp#on-windows) how to install the dependencies manually. The versions required for building Theia are:
- Python 3.6 or higher
-- Visual Studio [build tools](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2022) 17
+ - Visual Studio [build tools](https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2022) 17
- If you have multiple versions of either python or Visual Studio installed or if the tool is not found, you may adjust the used version via the npm config:
- `npm config set python /path/to/executable/python --global`
- `npm config set msvs_version 2017 --global`
diff --git a/packages/core/src/browser/style/menus.css b/packages/core/src/browser/style/menus.css
index ed0a4d2e209ea..ce0c6a1665a1e 100644
--- a/packages/core/src/browser/style/menus.css
+++ b/packages/core/src/browser/style/menus.css
@@ -128,6 +128,7 @@
color: var(--theia-menu-selectionForeground);
border: thin solid var(--theia-menu-selectionBorder);
opacity: 1;
+ cursor: pointer;
}
diff --git a/packages/core/src/common/index.ts b/packages/core/src/common/index.ts
index e82ecddfa1268..cedfd254d0009 100644
--- a/packages/core/src/common/index.ts
+++ b/packages/core/src/common/index.ts
@@ -34,6 +34,7 @@ export * from './message-service';
export * from './message-service-protocol';
export * from './progress-service';
export * from './progress-service-protocol';
+export * from './quick-pick-service';
export * from './selection';
export * from './strings';
export * from './application-error';
diff --git a/packages/core/src/electron-main/theia-electron-window.ts b/packages/core/src/electron-main/theia-electron-window.ts
index 8494ac75d720b..9ac8e7c9a2acd 100644
--- a/packages/core/src/electron-main/theia-electron-window.ts
+++ b/packages/core/src/electron-main/theia-electron-window.ts
@@ -20,8 +20,10 @@ import { APPLICATION_STATE_CHANGE_SIGNAL, CLOSE_REQUESTED_SIGNAL, RELOAD_REQUEST
import { BrowserWindow, BrowserWindowConstructorOptions, ipcMain, IpcMainEvent } from '../../electron-shared/electron';
import { inject, injectable, postConstruct } from '../../shared/inversify';
import { ElectronMainApplicationGlobals } from './electron-main-constants';
-import { DisposableCollection, Emitter, Event, isWindows } from '../common';
+import { DisposableCollection, Emitter, Event } from '../common';
import { createDisposableListener } from './event-utils';
+import { URI } from '../common/uri';
+import { FileUri } from '../node/file-uri';
/**
* Theia tracks the maximized state of Electron Browser Windows.
@@ -114,14 +116,15 @@ export class TheiaElectronWindow {
}
protected async handleStopRequest(onSafeCallback: () => unknown, reason: StopReason): Promise {
- // Only confirm close to windows that have loaded our front end.
- let currentUrl = this.window.webContents.getURL();
- let frontendUri = this.globals.THEIA_FRONTEND_HTML_PATH;
- // Since our resolved frontend HTML path might contain backward slashes on Windows, we normalize everything first.
- if (isWindows) {
- currentUrl = currentUrl.replace(/\\/g, '/');
- frontendUri = frontendUri.replace(/\\/g, '/');
- }
+ // Only confirm close to windows that have loaded our frontend.
+ // Both the windows's URL and the FS path of the `index.html` should be converted to the "same" format to be able to compare them. (#11226)
+ // Notes:
+ // - Windows: file:///C:/path/to/somewhere vs file:///c%3A/path/to/somewhere
+ // - macOS: file:///Applications/App%20Name.app/Contents vs /Applications/App Name.app/Contents
+ // This URL string comes from electron, we can expect that this is properly encoded URL. For example, a space is `%20`
+ const currentUrl = new URI(this.window.webContents.getURL()).toString();
+ // THEIA_FRONTEND_HTML_PATH is an FS path, we have to covert to an encoded URI string.
+ const frontendUri = FileUri.create(this.globals.THEIA_FRONTEND_HTML_PATH).toString();
const safeToClose = !currentUrl.includes(frontendUri) || await this.checkSafeToStop(reason);
if (safeToClose) {
try {
diff --git a/packages/debug/src/browser/debug-contribution.ts b/packages/debug/src/browser/debug-contribution.ts
index 882cb4d5c489d..48af1c8be8378 100644
--- a/packages/debug/src/browser/debug-contribution.ts
+++ b/packages/debug/src/browser/debug-contribution.ts
@@ -23,12 +23,6 @@ export interface DebugContribution {
register(configType: string, connection: DebugSessionConnection): void;
}
-export interface DebugPluginConfiguration {
- debugMode?: string;
- pluginLocation?: string;
- debugPort?: string;
-}
-
// copied from https://github.com/microsoft/vscode-node-debug2/blob/bcd333ef87642b817ac96d28fde7ab96fee3f6a9/src/nodeDebugInterfaces.d.ts
export interface LaunchVSCodeRequest extends DebugProtocol.Request {
arguments: LaunchVSCodeArguments;
diff --git a/packages/plugin-dev/src/browser/hosted-plugin-manager-client.ts b/packages/plugin-dev/src/browser/hosted-plugin-manager-client.ts
index 2cd28677e734d..95ff873e7b9f2 100644
--- a/packages/plugin-dev/src/browser/hosted-plugin-manager-client.ts
+++ b/packages/plugin-dev/src/browser/hosted-plugin-manager-client.ts
@@ -22,8 +22,8 @@ import { LabelProvider, isNative, AbstractDialog } from '@theia/core/lib/browser
import { WindowService } from '@theia/core/lib/browser/window/window-service';
import { WorkspaceService } from '@theia/workspace/lib/browser';
import { FileDialogService } from '@theia/filesystem/lib/browser';
-import { PluginDevServer } from '../common/plugin-dev-protocol';
-import { DebugPluginConfiguration, LaunchVSCodeArgument, LaunchVSCodeRequest, LaunchVSCodeResult } from '@theia/debug/lib/browser/debug-contribution';
+import { PluginDebugConfiguration, PluginDevServer } from '../common/plugin-dev-protocol';
+import { LaunchVSCodeArgument, LaunchVSCodeRequest, LaunchVSCodeResult } from '@theia/debug/lib/browser/debug-contribution';
import { DebugSessionManager } from '@theia/debug/lib/browser/debug-session-manager';
import { HostedPluginPreferences } from './hosted-plugin-preferences';
import { FileService } from '@theia/filesystem/lib/browser/file-service';
@@ -145,7 +145,7 @@ export class HostedPluginManagerClient {
return undefined;
}
- async start(debugConfig?: DebugPluginConfiguration): Promise {
+ async start(debugConfig?: PluginDebugConfiguration): Promise {
if (await this.hostedPluginServer.isHostedPluginInstanceRunning()) {
this.messageService.warn(nls.localize('theia/plugin-dev/alreadyRunning', 'Hosted instance is already running.'));
return;
@@ -181,7 +181,7 @@ export class HostedPluginManagerClient {
}
}
- async debug(config?: DebugPluginConfiguration): Promise {
+ async debug(config?: PluginDebugConfiguration): Promise {
await this.start(this.setDebugConfig(config));
await this.startDebugSessionManager();
@@ -361,7 +361,7 @@ export class HostedPluginManagerClient {
return error?.message?.substring(error.message.indexOf(':') + 1) || '';
}
- private setDebugConfig(config?: DebugPluginConfiguration): DebugPluginConfiguration {
+ private setDebugConfig(config?: PluginDebugConfiguration): PluginDebugConfiguration {
config = Object.assign(config || {}, { debugMode: this.hostedPluginPreferences['hosted-plugin.debugMode'] });
if (config.pluginLocation) {
this.pluginLocation = new URI((!config.pluginLocation.startsWith('/') ? '/' : '') + config.pluginLocation.replace(/\\/g, '/')).withScheme('file');
@@ -369,7 +369,7 @@ export class HostedPluginManagerClient {
return config;
}
- private getDebugPluginConfig(args: LaunchVSCodeArgument[]): DebugPluginConfiguration {
+ private getDebugPluginConfig(args: LaunchVSCodeArgument[]): PluginDebugConfiguration {
let pluginLocation;
for (const arg of args) {
if (arg?.prefix === '--extensionDevelopmentPath=') {
diff --git a/packages/plugin-dev/src/common/plugin-dev-protocol.ts b/packages/plugin-dev/src/common/plugin-dev-protocol.ts
index 18a5924b8f0a6..dc69da104e5fa 100644
--- a/packages/plugin-dev/src/common/plugin-dev-protocol.ts
+++ b/packages/plugin-dev/src/common/plugin-dev-protocol.ts
@@ -15,8 +15,6 @@
// *****************************************************************************
import { JsonRpcServer } from '@theia/core/lib/common/messaging/proxy-factory';
-// eslint-disable-next-line @theia/runtime-import-check
-import { DebugPluginConfiguration } from '@theia/debug/lib/browser/debug-contribution';
import { PluginMetadata } from '@theia/plugin-ext/lib/common/plugin-protocol';
export const pluginDevServicePath = '/services/plugin-dev';
@@ -24,7 +22,7 @@ export const PluginDevServer = Symbol('PluginDevServer');
export interface PluginDevServer extends JsonRpcServer {
getHostedPlugin(): Promise;
runHostedPluginInstance(uri: string): Promise;
- runDebugHostedPluginInstance(uri: string, debugConfig: DebugPluginConfiguration): Promise;
+ runDebugHostedPluginInstance(uri: string, debugConfig: PluginDebugConfiguration): Promise;
terminateHostedPluginInstance(): Promise;
isHostedPluginInstanceRunning(): Promise;
getHostedPluginInstanceURI(): Promise;
@@ -39,3 +37,9 @@ export interface PluginDevServer extends JsonRpcServer {
export interface PluginDevClient {
}
+
+export interface PluginDebugConfiguration {
+ debugMode?: string;
+ pluginLocation?: string;
+ debugPort?: string;
+}
diff --git a/packages/plugin-dev/src/node/hosted-instance-manager.ts b/packages/plugin-dev/src/node/hosted-instance-manager.ts
index c540d21fed6f4..c86deb06d9aa2 100644
--- a/packages/plugin-dev/src/node/hosted-instance-manager.ts
+++ b/packages/plugin-dev/src/node/hosted-instance-manager.ts
@@ -29,8 +29,7 @@ import { FileUri } from '@theia/core/lib/node/file-uri';
import { LogType } from '@theia/plugin-ext/lib/common/types';
import { HostedPluginSupport } from '@theia/plugin-ext/lib/hosted/node/hosted-plugin';
import { MetadataScanner } from '@theia/plugin-ext/lib/hosted/node/metadata-scanner';
-// eslint-disable-next-line @theia/runtime-import-check
-import { DebugPluginConfiguration } from '@theia/debug/lib/browser/debug-contribution';
+import { PluginDebugConfiguration } from '../common/plugin-dev-protocol';
import { HostedPluginProcess } from '@theia/plugin-ext/lib/hosted/node/hosted-plugin-process';
const DEFAULT_HOSTED_PLUGIN_PORT = 3030;
@@ -61,7 +60,7 @@ export interface HostedInstanceManager {
* @param debugConfig debug configuration
* @returns uri where new Theia instance is run
*/
- debug(pluginUri: URI, debugConfig: DebugPluginConfiguration): Promise;
+ debug(pluginUri: URI, debugConfig: PluginDebugConfiguration): Promise;
/**
* Terminates hosted plugin instance.
@@ -121,11 +120,11 @@ export abstract class AbstractHostedInstanceManager implements HostedInstanceMan
return this.doRun(pluginUri, port);
}
- async debug(pluginUri: URI, debugConfig: DebugPluginConfiguration): Promise {
+ async debug(pluginUri: URI, debugConfig: PluginDebugConfiguration): Promise {
return this.doRun(pluginUri, undefined, debugConfig);
}
- private async doRun(pluginUri: URI, port?: number, debugConfig?: DebugPluginConfiguration): Promise {
+ private async doRun(pluginUri: URI, port?: number, debugConfig?: PluginDebugConfiguration): Promise {
if (this.isPluginRunning) {
this.hostedPluginSupport.sendLog({ data: 'Hosted plugin instance is already running.', type: LogType.Info });
throw new Error('Hosted instance is already running.');
@@ -239,7 +238,7 @@ export abstract class AbstractHostedInstanceManager implements HostedInstanceMan
return false;
}
- protected async getStartCommand(port?: number, debugConfig?: DebugPluginConfiguration): Promise {
+ protected async getStartCommand(port?: number, debugConfig?: PluginDebugConfiguration): Promise {
const processArguments = process.argv;
let command: string[];
@@ -366,7 +365,7 @@ export class NodeHostedPluginRunner extends AbstractHostedInstanceManager {
return options;
}
- protected override async getStartCommand(port?: number, debugConfig?: DebugPluginConfiguration): Promise {
+ protected override async getStartCommand(port?: number, debugConfig?: PluginDebugConfiguration): Promise {
if (!port) {
port = process.env.HOSTED_PLUGIN_PORT ?
Number(process.env.HOSTED_PLUGIN_PORT) :
diff --git a/packages/plugin-dev/src/node/plugin-dev-service.ts b/packages/plugin-dev/src/node/plugin-dev-service.ts
index 5d8f346854e4a..58c0ecf566523 100644
--- a/packages/plugin-dev/src/node/plugin-dev-service.ts
+++ b/packages/plugin-dev/src/node/plugin-dev-service.ts
@@ -14,7 +14,7 @@
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
// *****************************************************************************
-import { PluginDevServer, PluginDevClient } from '../common/plugin-dev-protocol';
+import { PluginDebugConfiguration, PluginDevServer, PluginDevClient } from '../common/plugin-dev-protocol';
import { injectable, inject } from '@theia/core/shared/inversify';
import { HostedInstanceManager } from './hosted-instance-manager';
import { PluginMetadata } from '@theia/plugin-ext/lib/common/plugin-protocol';
@@ -22,8 +22,6 @@ import URI from '@theia/core/lib/common/uri';
import { HostedPluginReader } from './hosted-plugin-reader';
import { HostedPluginsManager } from './hosted-plugins-manager';
import { HostedPluginSupport } from '@theia/plugin-ext/lib/hosted/node/hosted-plugin';
-// eslint-disable-next-line @theia/runtime-import-check
-import { DebugPluginConfiguration } from '@theia/debug/lib/browser/debug-contribution';
@injectable()
export class PluginDevServerImpl implements PluginDevServer {
@@ -66,7 +64,7 @@ export class PluginDevServerImpl implements PluginDevServer {
return this.uriToStrPromise(this.hostedInstanceManager.run(new URI(uri)));
}
- runDebugHostedPluginInstance(uri: string, debugConfig: DebugPluginConfiguration): Promise {
+ runDebugHostedPluginInstance(uri: string, debugConfig: PluginDebugConfiguration): Promise {
return this.uriToStrPromise(this.hostedInstanceManager.debug(new URI(uri), debugConfig));
}
diff --git a/packages/plugin-ext/src/common/plugin-api-rpc.ts b/packages/plugin-ext/src/common/plugin-api-rpc.ts
index d533974845a91..abff12eabe343 100644
--- a/packages/plugin-ext/src/common/plugin-api-rpc.ts
+++ b/packages/plugin-ext/src/common/plugin-api-rpc.ts
@@ -99,8 +99,7 @@ import type {
import { SerializableEnvironmentVariableCollection } from '@theia/terminal/lib/common/base-terminal-protocol';
import { ThemeType } from '@theia/core/lib/common/theme';
import { Disposable } from '@theia/core/lib/common/disposable';
-// eslint-disable-next-line @theia/runtime-import-check
-import { PickOptions, QuickInputButtonHandle, QuickPickItem, WidgetOpenerOptions } from '@theia/core/lib/browser';
+import { PickOptions, QuickInputButtonHandle, QuickPickItem } from '@theia/core/lib/common';
import { Severity } from '@theia/core/lib/common/severity';
export interface PreferenceData {
@@ -1620,12 +1619,12 @@ export interface WebviewViewsMain extends Disposable {
}
export interface CustomEditorsExt {
- $resolveWebviewEditor(
+ $resolveWebviewEditor(
resource: UriComponents,
newWebviewHandle: string,
viewType: string,
title: string,
- widgetOpenerOptions: WidgetOpenerOptions | undefined,
+ widgetOpenerOptions: T | undefined,
options: theia.WebviewPanelOptions,
cancellation: CancellationToken): Promise;
$createCustomDocument(resource: UriComponents, viewType: string, openContext: theia.CustomDocumentOpenContext, cancellation: CancellationToken): Promise<{ editable: boolean }>;
@@ -1648,7 +1647,7 @@ export interface CustomEditorsMain {
$registerTextEditorProvider(viewType: string, options: theia.WebviewPanelOptions, capabilities: CustomTextEditorCapabilities): void;
$registerCustomEditorProvider(viewType: string, options: theia.WebviewPanelOptions, supportsMultipleEditorsPerDocument: boolean): void;
$unregisterEditorProvider(viewType: string): void;
- $createCustomEditorPanel(handle: string, title: string, widgetOpenerOptions: WidgetOpenerOptions | undefined, options: theia.WebviewPanelOptions & theia.WebviewOptions): Promise;
+ $createCustomEditorPanel(handle: string, title: string, widgetOpenerOptions: T | undefined, options: theia.WebviewPanelOptions & theia.WebviewOptions): Promise;
$onDidEdit(resource: UriComponents, viewType: string, editId: number, label: string | undefined): void;
$onContentChange(resource: UriComponents, viewType: string): void;
}
diff --git a/packages/plugin-ext/src/plugin/custom-editors.ts b/packages/plugin-ext/src/plugin/custom-editors.ts
index a1f956c5f5658..ae961bc294ee6 100644
--- a/packages/plugin-ext/src/plugin/custom-editors.ts
+++ b/packages/plugin-ext/src/plugin/custom-editors.ts
@@ -29,7 +29,6 @@ import { WebviewImpl, WebviewsExtImpl } from './webviews';
import { CancellationToken, CancellationTokenSource } from '@theia/core/lib/common/cancellation';
import { DisposableCollection } from '@theia/core/lib/common/disposable';
import { WorkspaceExtImpl } from './workspace';
-import { WidgetOpenerOptions } from '@theia/core/lib/browser';
export class CustomEditorsExtImpl implements CustomEditorsExt {
private readonly proxy: CustomEditorsMain;
@@ -116,12 +115,12 @@ export class CustomEditorsExtImpl implements CustomEditorsExt {
document.dispose();
}
- async $resolveWebviewEditor(
+ async $resolveWebviewEditor(
resource: UriComponents,
handler: string,
viewType: string,
title: string,
- widgetOpenerOptions: WidgetOpenerOptions | undefined,
+ widgetOpenerOptions: T | undefined,
options: theia.WebviewPanelOptions & theia.WebviewOptions,
cancellation: CancellationToken
): Promise {