Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/microsoft/vscode.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--extensions/git/src/repository.ts25
-rw-r--r--scripts/code-server.js2
-rw-r--r--src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts6
-rw-r--r--src/vs/code/electron-main/main.ts4
-rw-r--r--src/vs/platform/environment/common/environment.ts8
-rw-r--r--src/vs/platform/environment/common/environmentService.ts3
-rw-r--r--src/vs/platform/extensions/common/extensions.ts18
-rw-r--r--src/vs/platform/localizations/common/localizations.ts16
-rw-r--r--src/vs/platform/remote/common/remoteAuthorityResolver.ts6
-rw-r--r--src/vs/platform/remote/common/remoteHosts.ts22
-rw-r--r--src/vs/platform/tunnel/common/tunnel.ts (renamed from src/vs/platform/remote/common/tunnel.ts)7
-rw-r--r--src/vs/platform/tunnel/node/sharedProcessTunnelService.ts (renamed from src/vs/platform/remote/node/sharedProcessTunnelService.ts)2
-rw-r--r--src/vs/platform/tunnel/node/tunnelService.ts (renamed from src/vs/platform/remote/node/tunnelService.ts)2
-rw-r--r--src/vs/platform/webview/common/webviewPortMapping.ts2
-rw-r--r--src/vs/platform/workspace/common/virtualWorkspace.ts29
-rw-r--r--src/vs/server/node/remoteAgentEnvironmentImpl.ts5
-rw-r--r--src/vs/server/node/remoteExtensionHostAgentServer.ts41
-rw-r--r--src/vs/server/node/serverConnectionToken.ts (renamed from src/vs/server/node/connectionToken.ts)58
-rw-r--r--src/vs/server/node/serverEnvironmentService.ts3
-rw-r--r--src/vs/server/node/webClientServer.ts24
-rw-r--r--src/vs/server/test/node/serverConnectionToken.test.ts45
-rw-r--r--src/vs/workbench/api/browser/mainThreadSCM.ts4
-rw-r--r--src/vs/workbench/api/browser/mainThreadTunnelService.ts2
-rw-r--r--src/vs/workbench/api/common/extHost.protocol.ts9
-rw-r--r--src/vs/workbench/api/common/extHostSCM.ts12
-rw-r--r--src/vs/workbench/api/common/extHostTunnelService.ts2
-rw-r--r--src/vs/workbench/api/node/extHostTunnelService.ts2
-rw-r--r--src/vs/workbench/browser/contextkeys.ts3
-rw-r--r--src/vs/workbench/browser/layout.ts2
-rw-r--r--src/vs/workbench/browser/parts/titlebar/titlebarPart.ts2
-rw-r--r--src/vs/workbench/contrib/audioCues/browser/audioCueContribution.ts2
-rw-r--r--src/vs/workbench/contrib/audioCues/browser/media/break.opusbin27514 -> 9496 bytes
-rw-r--r--src/vs/workbench/contrib/audioCues/browser/media/error.opusbin26220 -> 8133 bytes
-rw-r--r--src/vs/workbench/contrib/audioCues/browser/media/foldedAreas.opusbin9722 -> 3094 bytes
-rw-r--r--src/vs/workbench/contrib/debug/browser/linkDetector.ts2
-rw-r--r--src/vs/workbench/contrib/debug/test/browser/linkDetector.test.ts2
-rw-r--r--src/vs/workbench/contrib/extensions/browser/extensionsActions.ts2
-rw-r--r--src/vs/workbench/contrib/extensions/browser/extensionsViews.ts2
-rw-r--r--src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts3
-rw-r--r--src/vs/workbench/contrib/remote/browser/remoteExplorer.ts2
-rw-r--r--src/vs/workbench/contrib/remote/browser/remoteIndicator.ts3
-rw-r--r--src/vs/workbench/contrib/remote/browser/tunnelView.ts3
-rw-r--r--src/vs/workbench/contrib/remote/common/tunnelFactory.ts2
-rw-r--r--src/vs/workbench/contrib/scm/browser/media/scm.css28
-rw-r--r--src/vs/workbench/contrib/scm/browser/scmViewPane.ts32
-rw-r--r--src/vs/workbench/contrib/scm/common/scm.ts9
-rw-r--r--src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts4
-rw-r--r--src/vs/workbench/contrib/terminal/browser/links/terminalBaseLinkProvider.ts4
-rw-r--r--src/vs/workbench/contrib/terminal/browser/links/terminalLink.ts9
-rw-r--r--src/vs/workbench/contrib/terminal/browser/links/terminalLinkManager.ts2
-rw-r--r--src/vs/workbench/contrib/terminal/browser/links/terminalProtocolLinkProvider.ts2
-rw-r--r--src/vs/workbench/contrib/terminal/browser/terminal.ts13
-rw-r--r--src/vs/workbench/contrib/terminal/browser/terminalInstance.ts39
-rw-r--r--src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts49
-rw-r--r--src/vs/workbench/contrib/terminal/common/terminal.ts7
-rw-r--r--src/vs/workbench/contrib/terminal/test/browser/links/terminalWordLinkProvider.test.ts151
-rw-r--r--src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts119
-rw-r--r--src/vs/workbench/contrib/webview/browser/webviewElement.ts2
-rw-r--r--src/vs/workbench/contrib/webview/electron-sandbox/webviewElement.ts2
-rw-r--r--src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts2
-rw-r--r--src/vs/workbench/contrib/workspace/browser/workspaceTrustEditor.ts2
-rw-r--r--src/vs/workbench/contrib/workspaces/browser/workspaces.contribution.ts2
-rw-r--r--src/vs/workbench/electron-sandbox/window.ts2
-rw-r--r--src/vs/workbench/services/environment/browser/environmentService.ts3
-rw-r--r--src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts2
-rw-r--r--src/vs/workbench/services/extensions/browser/extensionService.ts3
-rw-r--r--src/vs/workbench/services/extensions/common/abstractExtensionService.ts3
-rw-r--r--src/vs/workbench/services/extensions/common/extensionManifestPropertiesService.ts3
-rw-r--r--src/vs/workbench/services/extensions/common/extensionsRegistry.ts3
-rw-r--r--src/vs/workbench/services/extensions/electron-browser/extensionService.ts3
-rw-r--r--src/vs/workbench/services/path/common/pathService.ts2
-rw-r--r--src/vs/workbench/services/remote/common/remoteExplorerService.ts4
-rw-r--r--src/vs/workbench/services/tunnel/browser/tunnelService.ts (renamed from src/vs/workbench/services/remote/browser/tunnelService.ts)2
-rw-r--r--src/vs/workbench/services/tunnel/electron-sandbox/tunnelService.ts (renamed from src/vs/workbench/services/remote/electron-sandbox/tunnelService.ts)2
-rw-r--r--src/vs/workbench/services/workspaces/common/workspaceTrust.ts3
-rw-r--r--src/vs/workbench/workbench.sandbox.main.ts2
-rw-r--r--src/vs/workbench/workbench.web.api.ts2
-rw-r--r--src/vs/workbench/workbench.web.main.ts2
-rw-r--r--src/vscode-dts/vscode.proposed.scmActionButton.d.ts7
-rw-r--r--test/automation/src/playwrightDriver.ts3
80 files changed, 600 insertions, 318 deletions
diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts
index ed7096ad474..a2e8fd1a800 100644
--- a/extensions/git/src/repository.ts
+++ b/extensions/git/src/repository.ts
@@ -5,7 +5,7 @@
import * as fs from 'fs';
import * as path from 'path';
-import { CancellationToken, Command, Disposable, Event, EventEmitter, Memento, OutputChannel, ProgressLocation, ProgressOptions, scm, SourceControl, SourceControlInputBox, SourceControlInputBoxValidation, SourceControlInputBoxValidationType, SourceControlResourceDecorations, SourceControlResourceGroup, SourceControlResourceState, ThemeColor, Uri, window, workspace, WorkspaceEdit, FileDecoration, commands } from 'vscode';
+import { CancellationToken, Command, Disposable, Event, EventEmitter, Memento, OutputChannel, ProgressLocation, ProgressOptions, scm, SourceControl, SourceControlInputBox, SourceControlInputBoxValidation, SourceControlInputBoxValidationType, SourceControlResourceDecorations, SourceControlResourceGroup, SourceControlResourceState, ThemeColor, Uri, window, workspace, WorkspaceEdit, FileDecoration, commands, SourceControlActionButton } from 'vscode';
import TelemetryReporter from '@vscode/extension-telemetry';
import * as nls from 'vscode-nls';
import { Branch, Change, ForcePushMode, GitErrorCodes, LogOptions, Ref, RefType, Remote, Status, CommitOptions, BranchQuery, FetchOptions } from './api/git';
@@ -1935,7 +1935,7 @@ export class Repository implements Disposable {
return undefined;
});
- let actionButton: SourceControl['actionButton'];
+ let actionButton: SourceControlActionButton | undefined;
if (HEAD !== undefined) {
const config = workspace.getConfiguration('git', Uri.file(this.repository.root));
const showActionButton = config.get<string>('showUnpublishedCommitsButton', 'whenEmpty');
@@ -1948,18 +1948,23 @@ export class Repository implements Disposable {
const rebaseWhenSync = config.get<string>('rebaseWhenSync');
actionButton = {
- command: rebaseWhenSync ? 'git.syncRebase' : 'git.sync',
- title: localize('scm button sync title', '$(sync) Sync Changes {0}{1}', HEAD.behind ? `${HEAD.behind}$(arrow-down) ` : '', `${HEAD.ahead}$(arrow-up)`),
- tooltip: this.syncTooltip,
- arguments: [this._sourceControl],
+ command: {
+ command: rebaseWhenSync ? 'git.syncRebase' : 'git.sync',
+ title: localize('scm button sync title', "$(sync) {0}{1}", HEAD.behind ? `${HEAD.behind}$(arrow-down) ` : '', `${HEAD.ahead}$(arrow-up)`),
+ tooltip: this.syncTooltip,
+ arguments: [this._sourceControl],
+ },
+ description: localize('scm button sync description', "$(sync) Sync Changes {0}{1}", HEAD.behind ? `${HEAD.behind}$(arrow-down) ` : '', `${HEAD.ahead}$(arrow-up)`)
};
}
} else {
actionButton = {
- command: 'git.publish',
- title: localize('scm button publish title', "$(cloud-upload) Publish Branch"),
- tooltip: localize('scm button publish tooltip', "Publish Branch"),
- arguments: [this._sourceControl],
+ command: {
+ command: 'git.publish',
+ title: localize('scm button publish title', "$(cloud-upload) Publish Branch"),
+ tooltip: localize('scm button publish tooltip', "Publish Branch"),
+ arguments: [this._sourceControl],
+ }
};
}
}
diff --git a/scripts/code-server.js b/scripts/code-server.js
index 4ee2e88abc8..287b229bdda 100644
--- a/scripts/code-server.js
+++ b/scripts/code-server.js
@@ -40,7 +40,7 @@ const HOST = args['host'] ?? 'localhost';
const PORT = args['port'] ?? '9888';
const TOKEN = args['connection-token'] ?? String(crypto.randomInt(0xffffffff));
-if (args['launch'] && args['connection-token'] === undefined && args['connection-token-file'] === undefined && !args['no-connection-token']) {
+if (args['launch'] && args['connection-token'] === undefined && args['connection-token-file'] === undefined && !args['without-connection-token']) {
serverArgs.push('--connection-token', TOKEN);
}
if (args['host'] === undefined) {
diff --git a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts
index a4147b57382..2b6bc81dca2 100644
--- a/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts
+++ b/src/vs/code/electron-browser/sharedProcess/sharedProcessMain.ts
@@ -85,10 +85,10 @@ import { UserDataAutoSyncService } from 'vs/platform/userDataSync/electron-sandb
import { ActiveWindowManager } from 'vs/platform/windows/node/windowTracker';
import { ISignService } from 'vs/platform/sign/common/sign';
import { SignService } from 'vs/platform/sign/node/signService';
-import { ISharedTunnelsService } from 'vs/platform/remote/common/tunnel';
-import { SharedTunnelsService } from 'vs/platform/remote/node/tunnelService';
+import { ISharedTunnelsService } from 'vs/platform/tunnel/common/tunnel';
+import { SharedTunnelsService } from 'vs/platform/tunnel/node/tunnelService';
import { ipcSharedProcessTunnelChannelName, ISharedProcessTunnelService } from 'vs/platform/remote/common/sharedProcessTunnelService';
-import { SharedProcessTunnelService } from 'vs/platform/remote/node/sharedProcessTunnelService';
+import { SharedProcessTunnelService } from 'vs/platform/tunnel/node/sharedProcessTunnelService';
import { ipcSharedProcessWorkerChannelName, ISharedProcessWorkerConfiguration, ISharedProcessWorkerService } from 'vs/platform/sharedProcess/common/sharedProcessWorkerService';
import { SharedProcessWorkerService } from 'vs/platform/sharedProcess/electron-browser/sharedProcessWorkerService';
import { AssignmentService } from 'vs/platform/assignment/common/assignmentService';
diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts
index b607b95dc61..4ba46359de9 100644
--- a/src/vs/code/electron-main/main.ts
+++ b/src/vs/code/electron-main/main.ts
@@ -49,8 +49,8 @@ import product from 'vs/platform/product/common/product';
import { IProductService } from 'vs/platform/product/common/productService';
import { IProtocolMainService } from 'vs/platform/protocol/electron-main/protocol';
import { ProtocolMainService } from 'vs/platform/protocol/electron-main/protocolMainService';
-import { ITunnelService } from 'vs/platform/remote/common/tunnel';
-import { TunnelService } from 'vs/platform/remote/node/tunnelService';
+import { ITunnelService } from 'vs/platform/tunnel/common/tunnel';
+import { TunnelService } from 'vs/platform/tunnel/node/tunnelService';
import { IRequestService } from 'vs/platform/request/common/request';
import { RequestMainService } from 'vs/platform/request/electron-main/requestMainService';
import { ISignService } from 'vs/platform/sign/common/sign';
diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts
index d8f40bfb81d..22d030e30f4 100644
--- a/src/vs/platform/environment/common/environment.ts
+++ b/src/vs/platform/environment/common/environment.ts
@@ -5,7 +5,6 @@
import { URI } from 'vs/base/common/uri';
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
-import { ExtensionKind } from 'vs/platform/extensions/common/extensions';
import { createDecorator, refineServiceDecorator } from 'vs/platform/instantiation/common/instantiation';
export const IEnvironmentService = createDecorator<IEnvironmentService>('environmentService');
@@ -22,6 +21,13 @@ export interface IExtensionHostDebugParams extends IDebugParams {
}
/**
+ * Type of extension.
+ *
+ * **NOTE**: This is defined in `platform/environment` because it can appear as a CLI argument.
+ */
+export type ExtensionKind = 'ui' | 'workspace' | 'web';
+
+/**
* A basic environment service that can be used in various processes,
* such as main, renderer and shared process. Use subclasses of this
* service for specific environment.
diff --git a/src/vs/platform/environment/common/environmentService.ts b/src/vs/platform/environment/common/environmentService.ts
index 1ee4818dbf9..f2a3ea1b718 100644
--- a/src/vs/platform/environment/common/environmentService.ts
+++ b/src/vs/platform/environment/common/environmentService.ts
@@ -11,8 +11,7 @@ import { env } from 'vs/base/common/process';
import { joinPath } from 'vs/base/common/resources';
import { URI } from 'vs/base/common/uri';
import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
-import { IDebugParams, IExtensionHostDebugParams, INativeEnvironmentService } from 'vs/platform/environment/common/environment';
-import { ExtensionKind } from 'vs/platform/extensions/common/extensions';
+import { ExtensionKind, IDebugParams, IExtensionHostDebugParams, INativeEnvironmentService } from 'vs/platform/environment/common/environment';
import { IProductService } from 'vs/platform/product/common/productService';
export interface INativeEnvironmentPaths {
diff --git a/src/vs/platform/extensions/common/extensions.ts b/src/vs/platform/extensions/common/extensions.ts
index fa86a6e9aed..72d69909b9e 100644
--- a/src/vs/platform/extensions/common/extensions.ts
+++ b/src/vs/platform/extensions/common/extensions.ts
@@ -5,8 +5,8 @@
import * as strings from 'vs/base/common/strings';
import { URI } from 'vs/base/common/uri';
+import { ExtensionKind } from 'vs/platform/environment/common/environment';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
-import { ILocalization } from 'vs/platform/localizations/common/localizations';
import { getRemoteName } from 'vs/platform/remote/common/remoteHosts';
export const MANIFEST_CACHE_FOLDER = 'CachedExtensions';
@@ -159,6 +159,19 @@ export interface INotebookRendererContribution {
readonly mimeTypes: string[];
}
+export interface ITranslation {
+ id: string;
+ path: string;
+}
+
+export interface ILocalizationContribution {
+ languageId: string;
+ languageName?: string;
+ localizedLanguageName?: string;
+ translations: ITranslation[];
+ minimalTranslations?: { [key: string]: string };
+}
+
export interface IExtensionContributions {
commands?: ICommand[];
configuration?: IConfiguration | IConfiguration[];
@@ -175,7 +188,7 @@ export interface IExtensionContributions {
viewsContainers?: { [location: string]: IViewContainer[] };
views?: { [location: string]: IView[] };
colors?: IColor[];
- localizations?: ILocalization[];
+ localizations?: ILocalizationContribution[];
readonly customEditors?: readonly IWebviewEditor[];
readonly codeActions?: readonly ICodeActionContribution[];
authentication?: IAuthenticationContribution[];
@@ -192,7 +205,6 @@ export interface IExtensionCapabilities {
export const ALL_EXTENSION_KINDS: readonly ExtensionKind[] = ['ui', 'workspace', 'web'];
-export type ExtensionKind = 'ui' | 'workspace' | 'web';
export type LimitedWorkspaceSupportType = 'limited';
export type ExtensionUntrustedWorkspaceSupportType = boolean | LimitedWorkspaceSupportType;
diff --git a/src/vs/platform/localizations/common/localizations.ts b/src/vs/platform/localizations/common/localizations.ts
index 65e2dd9d4c4..6792440125c 100644
--- a/src/vs/platform/localizations/common/localizations.ts
+++ b/src/vs/platform/localizations/common/localizations.ts
@@ -3,28 +3,16 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
+import { ILocalizationContribution } from 'vs/platform/extensions/common/extensions';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
-export interface ILocalization {
- languageId: string;
- languageName?: string;
- localizedLanguageName?: string;
- translations: ITranslation[];
- minimalTranslations?: { [key: string]: string };
-}
-
-export interface ITranslation {
- id: string;
- path: string;
-}
-
export const ILocalizationsService = createDecorator<ILocalizationsService>('localizationsService');
export interface ILocalizationsService {
readonly _serviceBrand: undefined;
getLanguageIds(): Promise<string[]>;
}
-export function isValidLocalization(localization: ILocalization): boolean {
+export function isValidLocalization(localization: ILocalizationContribution): boolean {
if (typeof localization.languageId !== 'string') {
return false;
}
diff --git a/src/vs/platform/remote/common/remoteAuthorityResolver.ts b/src/vs/platform/remote/common/remoteAuthorityResolver.ts
index 570c9072e3b..fb899410b07 100644
--- a/src/vs/platform/remote/common/remoteAuthorityResolver.ts
+++ b/src/vs/platform/remote/common/remoteAuthorityResolver.ts
@@ -6,7 +6,6 @@
import { Event } from 'vs/base/common/event';
import { URI } from 'vs/base/common/uri';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
-import { TunnelPrivacy } from 'vs/platform/remote/common/tunnel';
export const IRemoteAuthorityResolverService = createDecorator<IRemoteAuthorityResolverService>('remoteAuthorityResolverService');
@@ -29,6 +28,11 @@ export interface TunnelDescription {
privacy?: string;
protocol?: string;
}
+export interface TunnelPrivacy {
+ themeIcon: string;
+ id: string;
+ label: string;
+}
export interface TunnelInformation {
environmentTunnels?: TunnelDescription[];
features?: {
diff --git a/src/vs/platform/remote/common/remoteHosts.ts b/src/vs/platform/remote/common/remoteHosts.ts
index 36675b64b39..c24b5295b2c 100644
--- a/src/vs/platform/remote/common/remoteHosts.ts
+++ b/src/vs/platform/remote/common/remoteHosts.ts
@@ -5,7 +5,6 @@
import { Schemas } from 'vs/base/common/network';
import { URI } from 'vs/base/common/uri';
-import { IWorkspace } from 'vs/platform/workspace/common/workspace';
export function getRemoteAuthority(uri: URI): string | undefined {
return uri.scheme === Schemas.vscodeRemote ? uri.authority : undefined;
@@ -25,24 +24,3 @@ export function getRemoteName(authority: string | undefined): string | undefined
}
return authority.substr(0, pos);
}
-
-export function isVirtualResource(resource: URI) {
- return resource.scheme !== Schemas.file && resource.scheme !== Schemas.vscodeRemote;
-}
-
-export function getVirtualWorkspaceLocation(workspace: IWorkspace): { scheme: string, authority: string } | undefined {
- if (workspace.folders.length) {
- return workspace.folders.every(f => isVirtualResource(f.uri)) ? workspace.folders[0].uri : undefined;
- } else if (workspace.configuration && isVirtualResource(workspace.configuration)) {
- return workspace.configuration;
- }
- return undefined;
-}
-
-export function getVirtualWorkspaceScheme(workspace: IWorkspace): string | undefined {
- return getVirtualWorkspaceLocation(workspace)?.scheme;
-}
-
-export function isVirtualWorkspace(workspace: IWorkspace): boolean {
- return getVirtualWorkspaceLocation(workspace) !== undefined;
-}
diff --git a/src/vs/platform/remote/common/tunnel.ts b/src/vs/platform/tunnel/common/tunnel.ts
index adb97ae8cf2..f4a174e37cf 100644
--- a/src/vs/platform/remote/common/tunnel.ts
+++ b/src/vs/platform/tunnel/common/tunnel.ts
@@ -11,6 +11,7 @@ import { URI } from 'vs/base/common/uri';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { ILogService } from 'vs/platform/log/common/log';
import { IAddressProvider } from 'vs/platform/remote/common/remoteAgentConnection';
+import { TunnelPrivacy } from 'vs/platform/remote/common/remoteAuthorityResolver';
export const ITunnelService = createDecorator<ITunnelService>('tunnelService');
export const ISharedTunnelsService = createDecorator<ISharedTunnelsService>('sharedTunnelsService');
@@ -49,12 +50,6 @@ export interface TunnelCreationOptions {
elevationRequired?: boolean;
}
-export interface TunnelPrivacy {
- themeIcon: string;
- id: string;
- label: string;
-}
-
export interface TunnelProviderFeatures {
elevation: boolean;
/**
diff --git a/src/vs/platform/remote/node/sharedProcessTunnelService.ts b/src/vs/platform/tunnel/node/sharedProcessTunnelService.ts
index fa7975c1891..ddea6ea6cdf 100644
--- a/src/vs/platform/remote/node/sharedProcessTunnelService.ts
+++ b/src/vs/platform/tunnel/node/sharedProcessTunnelService.ts
@@ -5,7 +5,7 @@
import { ILogService } from 'vs/platform/log/common/log';
import { ISharedProcessTunnel, ISharedProcessTunnelService } from 'vs/platform/remote/common/sharedProcessTunnelService';
-import { ISharedTunnelsService, RemoteTunnel } from 'vs/platform/remote/common/tunnel';
+import { ISharedTunnelsService, RemoteTunnel } from 'vs/platform/tunnel/common/tunnel';
import { IAddress, IAddressProvider } from 'vs/platform/remote/common/remoteAgentConnection';
import { Disposable } from 'vs/base/common/lifecycle';
import { canceled } from 'vs/base/common/errors';
diff --git a/src/vs/platform/remote/node/tunnelService.ts b/src/vs/platform/tunnel/node/tunnelService.ts
index 322b743d2c9..6aa019bf1e4 100644
--- a/src/vs/platform/remote/node/tunnelService.ts
+++ b/src/vs/platform/tunnel/node/tunnelService.ts
@@ -14,7 +14,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import { ILogService } from 'vs/platform/log/common/log';
import { IProductService } from 'vs/platform/product/common/productService';
import { connectRemoteAgentTunnel, IAddressProvider, IConnectionOptions, ISocketFactory } from 'vs/platform/remote/common/remoteAgentConnection';
-import { AbstractTunnelService, isAllInterfaces, ISharedTunnelsService as ISharedTunnelsService, isLocalhost, ITunnelService, RemoteTunnel, TunnelPrivacyId } from 'vs/platform/remote/common/tunnel';
+import { AbstractTunnelService, isAllInterfaces, ISharedTunnelsService as ISharedTunnelsService, isLocalhost, ITunnelService, RemoteTunnel, TunnelPrivacyId } from 'vs/platform/tunnel/common/tunnel';
import { ISignService } from 'vs/platform/sign/common/sign';
async function createRemoteTunnel(options: IConnectionOptions, defaultTunnelHost: string, tunnelRemoteHost: string, tunnelRemotePort: number, tunnelLocalPort?: number): Promise<RemoteTunnel> {
diff --git a/src/vs/platform/webview/common/webviewPortMapping.ts b/src/vs/platform/webview/common/webviewPortMapping.ts
index 5f7fafd3371..ee1014f7cce 100644
--- a/src/vs/platform/webview/common/webviewPortMapping.ts
+++ b/src/vs/platform/webview/common/webviewPortMapping.ts
@@ -7,7 +7,7 @@ import { IDisposable } from 'vs/base/common/lifecycle';
import { Schemas } from 'vs/base/common/network';
import { URI } from 'vs/base/common/uri';
import { IAddress } from 'vs/platform/remote/common/remoteAgentConnection';
-import { extractLocalHostUriMetaDataForPortMapping, ITunnelService, RemoteTunnel } from 'vs/platform/remote/common/tunnel';
+import { extractLocalHostUriMetaDataForPortMapping, ITunnelService, RemoteTunnel } from 'vs/platform/tunnel/common/tunnel';
export interface IWebviewPortMapping {
readonly webviewPort: number;
diff --git a/src/vs/platform/workspace/common/virtualWorkspace.ts b/src/vs/platform/workspace/common/virtualWorkspace.ts
new file mode 100644
index 00000000000..0dc19dde88e
--- /dev/null
+++ b/src/vs/platform/workspace/common/virtualWorkspace.ts
@@ -0,0 +1,29 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+import { Schemas } from 'vs/base/common/network';
+import { URI } from 'vs/base/common/uri';
+import { IWorkspace } from 'vs/platform/workspace/common/workspace';
+
+export function isVirtualResource(resource: URI) {
+ return resource.scheme !== Schemas.file && resource.scheme !== Schemas.vscodeRemote;
+}
+
+export function getVirtualWorkspaceLocation(workspace: IWorkspace): { scheme: string, authority: string } | undefined {
+ if (workspace.folders.length) {
+ return workspace.folders.every(f => isVirtualResource(f.uri)) ? workspace.folders[0].uri : undefined;
+ } else if (workspace.configuration && isVirtualResource(workspace.configuration)) {
+ return workspace.configuration;
+ }
+ return undefined;
+}
+
+export function getVirtualWorkspaceScheme(workspace: IWorkspace): string | undefined {
+ return getVirtualWorkspaceLocation(workspace)?.scheme;
+}
+
+export function isVirtualWorkspace(workspace: IWorkspace): boolean {
+ return getVirtualWorkspaceLocation(workspace) !== undefined;
+}
diff --git a/src/vs/server/node/remoteAgentEnvironmentImpl.ts b/src/vs/server/node/remoteAgentEnvironmentImpl.ts
index 9f842bfd971..e59722bb1dc 100644
--- a/src/vs/server/node/remoteAgentEnvironmentImpl.ts
+++ b/src/vs/server/node/remoteAgentEnvironmentImpl.ts
@@ -30,6 +30,7 @@ import { IExtensionManagementCLIService, InstallOptions } from 'vs/platform/exte
import { cwd } from 'vs/base/common/process';
import { Promises } from 'vs/base/node/pfs';
import { IProductService } from 'vs/platform/product/common/productService';
+import { ServerConnectionToken, ServerConnectionTokenType } from 'vs/server/node/serverConnectionToken';
let _SystemExtensionsRoot: string | null = null;
function getSystemExtensionsRoot(): string {
@@ -54,7 +55,7 @@ export class RemoteAgentEnvironmentChannel implements IServerChannel {
private readonly whenExtensionsReady: Promise<void>;
constructor(
- private readonly _connectionToken: string,
+ private readonly _connectionToken: ServerConnectionToken,
private readonly environmentService: IServerEnvironmentService,
extensionManagementCLIService: IExtensionManagementCLIService,
private readonly logService: ILogService,
@@ -310,7 +311,7 @@ export class RemoteAgentEnvironmentChannel implements IServerChannel {
private async _getEnvironmentData(): Promise<IRemoteAgentEnvironmentDTO> {
return {
pid: process.pid,
- connectionToken: this._connectionToken,
+ connectionToken: (this._connectionToken.type !== ServerConnectionTokenType.None ? this._connectionToken.value : ''),
appRoot: URI.file(this.environmentService.appRoot),
settingsPath: this.environmentService.machineSettingsResource,
logsPath: URI.file(this.environmentService.logsPath),
diff --git a/src/vs/server/node/remoteExtensionHostAgentServer.ts b/src/vs/server/node/remoteExtensionHostAgentServer.ts
index 9c44444a7c6..5498815eb21 100644
--- a/src/vs/server/node/remoteExtensionHostAgentServer.ts
+++ b/src/vs/server/node/remoteExtensionHostAgentServer.ts
@@ -34,7 +34,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur
import { IRequestService } from 'vs/platform/request/common/request';
import { RequestService } from 'vs/platform/request/node/requestService';
import { ITelemetryAppender, NullAppender, supportsTelemetry } from 'vs/platform/telemetry/common/telemetryUtils';
-import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
+import { ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { IExtensionGalleryService, IExtensionManagementCLIService, IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { ExtensionGalleryServiceWithNoStorageService } from 'vs/platform/extensionManagement/common/extensionGalleryService';
import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService';
@@ -83,7 +83,7 @@ import { ICredentialsMainService } from 'vs/platform/credentials/common/credenti
import { CredentialsMainService } from 'vs/platform/credentials/node/credentialsMainService';
import { EncryptionMainService } from 'vs/platform/encryption/node/encryptionMainService';
import { RemoteTelemetryChannel } from 'vs/server/node/remoteTelemetryChannel';
-import { parseConnectionToken, ServerConnectionTokenParseError } from 'vs/server/node/connectionToken';
+import { parseServerConnectionToken, ServerConnectionToken, ServerConnectionTokenParseError, ServerConnectionTokenType } from 'vs/server/node/serverConnectionToken';
import { IEncryptionMainService } from 'vs/platform/encryption/common/encryptionService';
const SHUTDOWN_TIMEOUT = 5 * 60 * 1000;
@@ -227,8 +227,7 @@ export class RemoteExtensionHostAgentServer extends Disposable {
constructor(
private readonly _environmentService: IServerEnvironmentService,
private readonly _productService: IProductService,
- private readonly _connectionToken: string,
- private readonly _connectionTokenIsMandatory: boolean,
+ private readonly _connectionToken: ServerConnectionToken,
hasWebClient: boolean,
REMOTE_DATA_FOLDER: string
) {
@@ -306,8 +305,19 @@ export class RemoteExtensionHostAgentServer extends Disposable {
commonProperties: resolveCommonProperties(fileService, release(), hostname(), process.arch, this._productService.commit, this._productService.version + '-remote', machineId, this._productService.msftInternalDomains, this._environmentService.installSourcePath, 'remoteAgent'),
piiPaths: [this._environmentService.appRoot]
};
-
- services.set(IRemoteTelemetryService, new SyncDescriptor(RemoteTelemetryService, [config, undefined]));
+ const initialTelemetryLevelArg = this._environmentService.args['telemetry-level'];
+ let injectedTelemetryLevel: TelemetryLevel | undefined = undefined;
+ // Convert the passed in CLI argument into a telemetry level for the telemetry service
+ if (initialTelemetryLevelArg === 'all') {
+ injectedTelemetryLevel = TelemetryLevel.USAGE;
+ } else if (initialTelemetryLevelArg === 'error') {
+ injectedTelemetryLevel = TelemetryLevel.ERROR;
+ } else if (initialTelemetryLevelArg === 'crash') {
+ injectedTelemetryLevel = TelemetryLevel.CRASH;
+ } else if (initialTelemetryLevelArg !== undefined) {
+ injectedTelemetryLevel = TelemetryLevel.NONE;
+ }
+ services.set(IRemoteTelemetryService, new SyncDescriptor(RemoteTelemetryService, [config, injectedTelemetryLevel]));
} else {
services.set(IRemoteTelemetryService, RemoteNullTelemetryService);
}
@@ -414,7 +424,7 @@ export class RemoteExtensionHostAgentServer extends Disposable {
if (pathname === '/vscode-remote-resource') {
// Handle HTTP requests for resources rendered in the rich client (images, fonts, etc.)
// These resources could be files shipped with extensions or even workspace files.
- if (parsedUrl.query['tkn'] !== this._connectionToken) {
+ if (!this._connectionToken.validate(parsedUrl.query['tkn'])) {
return serveError(req, res, 403, `Forbidden.`);
}
@@ -612,7 +622,7 @@ export class RemoteExtensionHostAgentServer extends Disposable {
return rejectWebSocketConnection(`Invalid first message`);
}
- if (this._connectionTokenIsMandatory && msg1.auth !== this._connectionToken) {
+ if (this._connectionToken.type === ServerConnectionTokenType.Mandatory && !this._connectionToken.validate(msg1.auth)) {
return rejectWebSocketConnection(`Unauthorized client refused: auth mismatch`);
}
@@ -667,7 +677,7 @@ export class RemoteExtensionHostAgentServer extends Disposable {
let valid = false;
if (!validator) {
valid = true;
- } else if (msg2.signedData === this._connectionToken) {
+ } else if (this._connectionToken.validate(msg2.signedData)) {
// web client
valid = true;
} else {
@@ -987,21 +997,20 @@ export async function createServer(address: string | net.AddressInfo | null, arg
}
}
- const connectionTokenParseResult = parseConnectionToken(args);
- if (connectionTokenParseResult instanceof ServerConnectionTokenParseError) {
- console.warn(connectionTokenParseResult.message);
+ const connectionToken = parseServerConnectionToken(args);
+ if (connectionToken instanceof ServerConnectionTokenParseError) {
+ console.warn(connectionToken.message);
process.exit(1);
}
- const connectionToken = connectionTokenParseResult.value;
- const connectionTokenIsMandatory = connectionTokenParseResult.isMandatory;
const hasWebClient = fs.existsSync(FileAccess.asFileUri('vs/code/browser/workbench/workbench.html', require).fsPath);
if (hasWebClient && address && typeof address !== 'string') {
// ships the web ui!
- console.log(`Web UI available at http://${args.host || 'localhost'}${address.port === 80 ? '' : `:${address.port}`}/?tkn=${connectionToken}`);
+ const queryPart = (connectionToken.type !== ServerConnectionTokenType.None ? `?tkn=${connectionToken.value}` : '');
+ console.log(`Web UI available at http://localhost${address.port === 80 ? '' : `:${address.port}`}/${queryPart}`);
}
- const remoteExtensionHostAgentServer = new RemoteExtensionHostAgentServer(environmentService, productService, connectionToken, connectionTokenIsMandatory, hasWebClient, REMOTE_DATA_FOLDER);
+ const remoteExtensionHostAgentServer = new RemoteExtensionHostAgentServer(environmentService, productService, connectionToken, hasWebClient, REMOTE_DATA_FOLDER);
const services = await remoteExtensionHostAgentServer.initialize();
const { telemetryService } = services;
diff --git a/src/vs/server/node/connectionToken.ts b/src/vs/server/node/serverConnectionToken.ts
index 7dda233d25c..6d169289a17 100644
--- a/src/vs/server/node/connectionToken.ts
+++ b/src/vs/server/node/serverConnectionToken.ts
@@ -9,21 +9,51 @@ import { ServerParsedArgs } from 'vs/server/node/serverEnvironmentService';
const connectionTokenRegex = /^[0-9A-Za-z-]+$/;
-export class ServerConnectionToken {
- constructor(
- public readonly value: string,
- public readonly isMandatory: boolean,
- ) {
+export const enum ServerConnectionTokenType {
+ None,
+ Optional,// TODO: Remove this soon
+ Mandatory
+}
+
+export class NoneServerConnectionToken {
+ public readonly type = ServerConnectionTokenType.None;
+
+ public validate(connectionToken: any): boolean {
+ return true;
}
}
+export class OptionalServerConnectionToken {
+ public readonly type = ServerConnectionTokenType.Optional;
+
+ constructor(public readonly value: string) {
+ }
+
+ public validate(connectionToken: any): boolean {
+ return (connectionToken === this.value);
+ }
+}
+
+export class MandatoryServerConnectionToken {
+ public readonly type = ServerConnectionTokenType.Mandatory;
+
+ constructor(public readonly value: string) {
+ }
+
+ public validate(connectionToken: any): boolean {
+ return (connectionToken === this.value);
+ }
+}
+
+export type ServerConnectionToken = NoneServerConnectionToken | OptionalServerConnectionToken | MandatoryServerConnectionToken;
+
export class ServerConnectionTokenParseError {
constructor(
public readonly message: string
- ) {}
+ ) { }
}
-export function parseConnectionToken(args: ServerParsedArgs): ServerConnectionToken | ServerConnectionTokenParseError {
+export function parseServerConnectionToken(args: ServerParsedArgs): ServerConnectionToken | ServerConnectionTokenParseError {
const withoutConnectionToken = args['without-connection-token'];
const connectionToken = args['connection-token'];
const connectionTokenFile = args['connection-token-file'];
@@ -33,7 +63,7 @@ export function parseConnectionToken(args: ServerParsedArgs): ServerConnectionTo
if (typeof connectionToken !== 'undefined' || typeof connectionTokenFile !== 'undefined') {
return new ServerConnectionTokenParseError(`Please do not use the argument '--connection-token' or '--connection-token-file' at the same time as '--without-connection-token'.`);
}
- return new ServerConnectionToken('without-connection-token' /* to be implemented @alexd */, false);
+ return new NoneServerConnectionToken();
}
if (typeof connectionTokenFile !== 'undefined') {
@@ -52,7 +82,7 @@ export function parseConnectionToken(args: ServerParsedArgs): ServerConnectionTo
return new ServerConnectionTokenParseError(`The connection token defined in '${connectionTokenFile} does not adhere to the characters 0-9, a-z, A-Z or -.`);
}
- return new ServerConnectionToken(rawConnectionToken, true);
+ return new MandatoryServerConnectionToken(rawConnectionToken);
}
if (typeof connectionToken !== 'undefined') {
@@ -62,19 +92,17 @@ export function parseConnectionToken(args: ServerParsedArgs): ServerConnectionTo
if (compatibility) {
// TODO: Remove this case soon
- return new ServerConnectionToken(connectionToken, false);
+ return new OptionalServerConnectionToken(connectionToken);
}
- return new ServerConnectionToken(connectionToken, true);
+ return new MandatoryServerConnectionToken(connectionToken);
}
if (compatibility) {
// TODO: Remove this case soon
console.log(`Breaking change in the next release: Please use one of the following arguments: '--connection-token', '--connection-token-file' or '--without-connection-token'.`);
- return new ServerConnectionToken(generateUuid(), false);
+ return new OptionalServerConnectionToken(generateUuid());
}
- // TODO: fixme
- return new ServerConnectionToken(generateUuid(), false);
- // return new ServerConnectionTokenParseError(`Please use one of the following arguments: '--connection-token', '--connection-token-file' or '--without-connection-token'.`);
+ return new ServerConnectionTokenParseError(`Please use one of the following arguments: '--connection-token', '--connection-token-file' or '--without-connection-token'.`);
}
diff --git a/src/vs/server/node/serverEnvironmentService.ts b/src/vs/server/node/serverEnvironmentService.ts
index 8250c06d7b2..1f93531ca3c 100644
--- a/src/vs/server/node/serverEnvironmentService.ts
+++ b/src/vs/server/node/serverEnvironmentService.ts
@@ -26,6 +26,7 @@ export const serverOptions: OptionDescriptions<ServerParsedArgs> = {
'print-ip-address': { type: 'boolean' },
'accept-server-license-terms': { type: 'boolean', cat: 'o', description: nls.localize('acceptLicenseTerms', 'If set, the user accepts the server license terms and the server will be started without a user prompt.') },
'server-data-dir': { type: 'string', cat: 'o', description: nls.localize('serverDataDir', 'Specifies the directory that server data is kept in.') },
+ 'telemetry-level': { type: 'string', cat: 'o', args: 'off | crash | error | all', description: nls.localize('telemetry-level', 'Sets the initial telemetry level. If not specified, the server will await a connection before sending any telemetry. Setting this to off is equivalent to --disable-telemetry') },
/* ----- vs code options ----- */
@@ -127,6 +128,8 @@ export interface ServerParsedArgs {
'server-data-dir'?: string;
+ 'telemetry-level'?: string;
+
/* ----- vs code options ----- */
'user-data-dir'?: string;
diff --git a/src/vs/server/node/webClientServer.ts b/src/vs/server/node/webClientServer.ts
index 259d0b0373c..64e2ed2489d 100644
--- a/src/vs/server/node/webClientServer.ts
+++ b/src/vs/server/node/webClientServer.ts
@@ -18,6 +18,7 @@ import { extname, dirname, join, normalize } from 'vs/base/common/path';
import { FileAccess } from 'vs/base/common/network';
import { generateUuid } from 'vs/base/common/uuid';
import { IProductService } from 'vs/platform/product/common/productService';
+import { ServerConnectionToken, ServerConnectionTokenType } from 'vs/server/node/serverConnectionToken';
const textMimeType = {
'.html': 'text/html',
@@ -73,7 +74,7 @@ const APP_ROOT = dirname(FileAccess.asFileUri('', require).fsPath);
export class WebClientServer {
constructor(
- private readonly _connectionToken: string,
+ private readonly _connectionToken: ServerConnectionToken,
private readonly _environmentService: IServerEnvironmentService,
private readonly _logService: ILogService,
private readonly _productService: IProductService
@@ -111,7 +112,7 @@ export class WebClientServer {
private _hasCorrectTokenCookie(req: http.IncomingMessage): boolean {
const cookies = cookie.parse(req.headers.cookie || '');
- return (cookies['vscode-tkn'] === this._connectionToken);
+ return this._connectionToken.validate(cookies['vscode-tkn']);
}
/**
@@ -207,14 +208,25 @@ export class WebClientServer {
'manifest-src \'self\';'
].join(' ');
- res.writeHead(200, {
+ const headers: http.OutgoingHttpHeaders = {
'Content-Type': 'text/html',
+ 'Content-Security-Policy': cspDirectives
+ };
+ if (this._connectionToken.type !== ServerConnectionTokenType.None) {
// At this point we know the client has a valid cookie
// and we want to set it prolong it to ensure that this
// client is valid for another 1 week at least
- 'Set-Cookie': cookie.serialize('vscode-tkn', this._connectionToken, { sameSite: 'strict', maxAge: 60 * 60 * 24 * 7 /* 1 week */ }),
- 'Content-Security-Policy': cspDirectives
- });
+ headers['Set-Cookie'] = cookie.serialize(
+ 'vscode-tkn',
+ this._connectionToken.value,
+ {
+ sameSite: 'strict',
+ maxAge: 60 * 60 * 24 * 7 /* 1 week */
+ }
+ );
+ }
+
+ res.writeHead(200, headers);
return res.end(data);
}
diff --git a/src/vs/server/test/node/serverConnectionToken.test.ts b/src/vs/server/test/node/serverConnectionToken.test.ts
index bbfa17f0c45..cea6d7ac4a5 100644
--- a/src/vs/server/test/node/serverConnectionToken.test.ts
+++ b/src/vs/server/test/node/serverConnectionToken.test.ts
@@ -7,7 +7,7 @@ import * as assert from 'assert';
import * as os from 'os';
import * as path from 'path';
import { getRandomTestPath } from 'vs/base/test/node/testUtils';
-import { parseConnectionToken, ServerConnectionToken, ServerConnectionTokenParseError } from 'vs/server/node/connectionToken';
+import { parseServerConnectionToken, ServerConnectionToken, ServerConnectionTokenParseError, ServerConnectionTokenType } from 'vs/server/node/serverConnectionToken';
import { ServerParsedArgs } from 'vs/server/node/serverEnvironmentService';
import { Promises } from 'vs/base/node/pfs';
@@ -21,33 +21,32 @@ suite('parseServerConnectionToken', () => {
assert.strictEqual(isError(r), true);
}
- // test('no arguments results in error', () => {
- // assertIsError(parseConnectionToken({} as ServerParsedArgs));
- // });
+ test('no arguments results in error', () => {
+ assertIsError(parseServerConnectionToken({} as ServerParsedArgs));
+ });
test('no arguments with --compatibility generates a token that is not mandatory', () => {
- const result = parseConnectionToken({ 'compatibility': '1.63' } as ServerParsedArgs);
- assert.ok(result instanceof ServerConnectionToken);
- assert.strictEqual(result.isMandatory, false);
+ const result = parseServerConnectionToken({ 'compatibility': '1.63' } as ServerParsedArgs);
+ assert.ok(!(result instanceof ServerConnectionTokenParseError));
+ assert.ok(result.type === ServerConnectionTokenType.Optional);
});
test('--without-connection-token', () => {
- const result = parseConnectionToken({ 'without-connection-token': true } as ServerParsedArgs);
- assert.ok(result instanceof ServerConnectionToken);
- assert.strictEqual(result.value, 'without-connection-token');
- assert.strictEqual(result.isMandatory, false);
+ const result = parseServerConnectionToken({ 'without-connection-token': true } as ServerParsedArgs);
+ assert.ok(!(result instanceof ServerConnectionTokenParseError));
+ assert.ok(result.type === ServerConnectionTokenType.None);
});
test('--without-connection-token --connection-token results in error', () => {
- assertIsError(parseConnectionToken({ 'without-connection-token': true, 'connection-token': '0' } as ServerParsedArgs));
+ assertIsError(parseServerConnectionToken({ 'without-connection-token': true, 'connection-token': '0' } as ServerParsedArgs));
});
test('--without-connection-token --connection-token-file results in error', () => {
- assertIsError(parseConnectionToken({ 'without-connection-token': true, 'connection-token-file': '0' } as ServerParsedArgs));
+ assertIsError(parseServerConnectionToken({ 'without-connection-token': true, 'connection-token-file': '0' } as ServerParsedArgs));
});
test('--connection-token-file --connection-token results in error', async () => {
- assertIsError(parseConnectionToken({ 'connection-token-file': '0', 'connection-token': '0' } as ServerParsedArgs));
+ assertIsError(parseServerConnectionToken({ 'connection-token-file': '0', 'connection-token': '0' } as ServerParsedArgs));
});
test('--connection-token-file', async () => {
@@ -56,26 +55,26 @@ suite('parseServerConnectionToken', () => {
const filename = path.join(testDir, 'connection-token-file');
const connectionToken = `12345-123-abc`;
await Promises.writeFile(filename, connectionToken);
- const result = parseConnectionToken({ 'connection-token-file': filename } as ServerParsedArgs);
- assert.ok(result instanceof ServerConnectionToken);
+ const result = parseServerConnectionToken({ 'connection-token-file': filename } as ServerParsedArgs);
+ assert.ok(!(result instanceof ServerConnectionTokenParseError));
+ assert.ok(result.type === ServerConnectionTokenType.Mandatory);
assert.strictEqual(result.value, connectionToken);
- assert.strictEqual(result.isMandatory, true);
await Promises.rm(testDir);
});
test('--connection-token', async () => {
const connectionToken = `12345-123-abc`;
- const result = parseConnectionToken({ 'connection-token': connectionToken } as ServerParsedArgs);
- assert.ok(result instanceof ServerConnectionToken);
+ const result = parseServerConnectionToken({ 'connection-token': connectionToken } as ServerParsedArgs);
+ assert.ok(!(result instanceof ServerConnectionTokenParseError));
+ assert.ok(result.type === ServerConnectionTokenType.Mandatory);
assert.strictEqual(result.value, connectionToken);
- assert.strictEqual(result.isMandatory, true);
});
test('--connection-token --compatibility marks a as not mandatory', async () => {
const connectionToken = `12345-123-abc`;
- const result = parseConnectionToken({ 'connection-token': connectionToken, 'compatibility': '1.63' } as ServerParsedArgs);
- assert.ok(result instanceof ServerConnectionToken);
+ const result = parseServerConnectionToken({ 'connection-token': connectionToken, 'compatibility': '1.63' } as ServerParsedArgs);
+ assert.ok(!(result instanceof ServerConnectionTokenParseError));
+ assert.ok(result.type === ServerConnectionTokenType.Optional);
assert.strictEqual(result.value, connectionToken);
- assert.strictEqual(result.isMandatory, false);
});
});
diff --git a/src/vs/workbench/api/browser/mainThreadSCM.ts b/src/vs/workbench/api/browser/mainThreadSCM.ts
index 60b414cf488..6a7c8bad373 100644
--- a/src/vs/workbench/api/browser/mainThreadSCM.ts
+++ b/src/vs/workbench/api/browser/mainThreadSCM.ts
@@ -6,7 +6,7 @@
import { URI, UriComponents } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event';
import { IDisposable, DisposableStore, combinedDisposable } from 'vs/base/common/lifecycle';
-import { ISCMService, ISCMRepository, ISCMProvider, ISCMResource, ISCMResourceGroup, ISCMResourceDecorations, IInputValidation, ISCMViewService, InputValidationType } from 'vs/workbench/contrib/scm/common/scm';
+import { ISCMService, ISCMRepository, ISCMProvider, ISCMResource, ISCMResourceGroup, ISCMResourceDecorations, IInputValidation, ISCMViewService, InputValidationType, ISCMActionButtonDescriptor } from 'vs/workbench/contrib/scm/common/scm';
import { ExtHostContext, MainThreadSCMShape, ExtHostSCMShape, SCMProviderFeatures, SCMRawResourceSplices, SCMGroupFeatures, MainContext, IExtHostContext } from '../common/extHost.protocol';
import { Command } from 'vs/editor/common/languages';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
@@ -120,7 +120,7 @@ class MainThreadSCMProvider implements ISCMProvider {
get commitTemplate(): string { return this.features.commitTemplate || ''; }
get acceptInputCommand(): Command | undefined { return this.features.acceptInputCommand; }
- get actionButton(): Command | undefined { return this.features.actionButton ?? undefined; }
+ get actionButton(): ISCMActionButtonDescriptor | undefined { return this.features.actionButton ?? undefined; }
get statusBarCommands(): Command[] | undefined { return this.features.statusBarCommands; }
get count(): number | undefined { return this.features.count; }
diff --git a/src/vs/workbench/api/browser/mainThreadTunnelService.ts b/src/vs/workbench/api/browser/mainThreadTunnelService.ts
index e0127baa03e..924fa83ab9d 100644
--- a/src/vs/workbench/api/browser/mainThreadTunnelService.ts
+++ b/src/vs/workbench/api/browser/mainThreadTunnelService.ts
@@ -8,7 +8,7 @@ import { MainThreadTunnelServiceShape, IExtHostContext, MainContext, ExtHostCont
import { TunnelDto } from 'vs/workbench/api/common/extHostTunnelService';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { CandidatePort, IRemoteExplorerService, makeAddress, PORT_AUTO_FORWARD_SETTING, PORT_AUTO_SOURCE_SETTING, PORT_AUTO_SOURCE_SETTING_OUTPUT, PORT_AUTO_SOURCE_SETTING_PROCESS, TunnelSource } from 'vs/workbench/services/remote/common/remoteExplorerService';
-import { ITunnelProvider, ITunnelService, TunnelCreationOptions, TunnelProviderFeatures, TunnelOptions, RemoteTunnel, isPortPrivileged, ProvidedPortAttributes, PortAttributesProvider, TunnelProtocol } from 'vs/platform/remote/common/tunnel';
+import { ITunnelProvider, ITunnelService, TunnelCreationOptions, TunnelProviderFeatures, TunnelOptions, RemoteTunnel, isPortPrivileged, ProvidedPortAttributes, PortAttributesProvider, TunnelProtocol } from 'vs/platform/tunnel/common/tunnel';
import { Disposable } from 'vs/base/common/lifecycle';
import type { TunnelDescription } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts
index f5c4d47c56b..b5bc807f568 100644
--- a/src/vs/workbench/api/common/extHost.protocol.ts
+++ b/src/vs/workbench/api/common/extHost.protocol.ts
@@ -34,7 +34,7 @@ import { IMarkerData } from 'vs/platform/markers/common/markers';
import { IProgressOptions, IProgressStep } from 'vs/platform/progress/common/progress';
import * as quickInput from 'vs/platform/quickinput/common/quickInput';
import { IRemoteConnectionData, RemoteAuthorityResolverErrorCode, ResolverResult, TunnelDescription } from 'vs/platform/remote/common/remoteAuthorityResolver';
-import { ProvidedPortAttributes, TunnelCreationOptions, TunnelOptions, TunnelProviderFeatures } from 'vs/platform/remote/common/tunnel';
+import { ProvidedPortAttributes, TunnelCreationOptions, TunnelOptions, TunnelProviderFeatures } from 'vs/platform/tunnel/common/tunnel';
import { ClassifiedEvent, GDPRClassification, StrictPropertyCheck } from 'vs/platform/telemetry/common/gdprTypings';
import { ITelemetryInfo, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { ICreateContributedTerminalProfileOptions, IProcessProperty, IShellLaunchConfigDto, ITerminalEnvironment, ITerminalLaunchError, ITerminalProfile, TerminalLocation } from 'vs/platform/terminal/common/terminal';
@@ -1085,10 +1085,15 @@ export interface SCMProviderFeatures {
count?: number;
commitTemplate?: string;
acceptInputCommand?: modes.Command;
- actionButton?: ICommandDto | null;
+ actionButton?: SCMActionButtonDto | null;
statusBarCommands?: ICommandDto[];
}
+export interface SCMActionButtonDto {
+ command: ICommandDto;
+ description?: string;
+}
+
export interface SCMGroupFeatures {
hideWhenEmpty?: boolean;
}
diff --git a/src/vs/workbench/api/common/extHostSCM.ts b/src/vs/workbench/api/common/extHostSCM.ts
index 8a9effffd6b..34c5bbf5176 100644
--- a/src/vs/workbench/api/common/extHostSCM.ts
+++ b/src/vs/workbench/api/common/extHostSCM.ts
@@ -506,18 +506,22 @@ class ExtHostSourceControl implements vscode.SourceControl {
}
private _actionButtonDisposables = new MutableDisposable<DisposableStore>();
- private _actionButton: vscode.Command | undefined;
- get actionButton(): vscode.Command | undefined {
+ private _actionButton: vscode.SourceControlActionButton | undefined;
+ get actionButton(): vscode.SourceControlActionButton | undefined {
checkProposedApiEnabled(this._extension, 'scmActionButton');
return this._actionButton;
}
- set actionButton(actionButton: vscode.Command | undefined) {
+ set actionButton(actionButton: vscode.SourceControlActionButton | undefined) {
checkProposedApiEnabled(this._extension, 'scmActionButton');
this._actionButtonDisposables.value = new DisposableStore();
this._actionButton = actionButton;
- const internal = actionButton !== undefined ? this._commands.converter.toInternal(this._actionButton, this._actionButtonDisposables.value) : undefined;
+ const internal = actionButton !== undefined ?
+ {
+ command: this._commands.converter.toInternal(actionButton.command, this._actionButtonDisposables.value),
+ description: actionButton.description
+ } : undefined;
this.#proxy.$updateSourceControl(this.handle, { actionButton: internal ?? null });
}
diff --git a/src/vs/workbench/api/common/extHostTunnelService.ts b/src/vs/workbench/api/common/extHostTunnelService.ts
index e861d188f72..461db2f4499 100644
--- a/src/vs/workbench/api/common/extHostTunnelService.ts
+++ b/src/vs/workbench/api/common/extHostTunnelService.ts
@@ -6,7 +6,7 @@
import { ExtHostTunnelServiceShape } from 'vs/workbench/api/common/extHost.protocol';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import * as vscode from 'vscode';
-import { ProvidedPortAttributes, RemoteTunnel, TunnelCreationOptions, TunnelOptions, TunnelPrivacyId } from 'vs/platform/remote/common/tunnel';
+import { ProvidedPortAttributes, RemoteTunnel, TunnelCreationOptions, TunnelOptions, TunnelPrivacyId } from 'vs/platform/tunnel/common/tunnel';
import { IDisposable } from 'vs/base/common/lifecycle';
import { Emitter } from 'vs/base/common/event';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
diff --git a/src/vs/workbench/api/node/extHostTunnelService.ts b/src/vs/workbench/api/node/extHostTunnelService.ts
index 03d0f5229f8..f480c0fa3e7 100644
--- a/src/vs/workbench/api/node/extHostTunnelService.ts
+++ b/src/vs/workbench/api/node/extHostTunnelService.ts
@@ -17,7 +17,7 @@ import * as types from 'vs/workbench/api/common/extHostTypes';
import { isLinux } from 'vs/base/common/platform';
import { IExtHostTunnelService, TunnelDto } from 'vs/workbench/api/common/extHostTunnelService';
import { Event, Emitter } from 'vs/base/common/event';
-import { TunnelOptions, TunnelCreationOptions, ProvidedPortAttributes, ProvidedOnAutoForward, isLocalhost, isAllInterfaces } from 'vs/platform/remote/common/tunnel';
+import { TunnelOptions, TunnelCreationOptions, ProvidedPortAttributes, ProvidedOnAutoForward, isLocalhost, isAllInterfaces } from 'vs/platform/tunnel/common/tunnel';
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { MovingAverage } from 'vs/base/common/numbers';
import { CandidatePort } from 'vs/workbench/services/remote/common/remoteExplorerService';
diff --git a/src/vs/workbench/browser/contextkeys.ts b/src/vs/workbench/browser/contextkeys.ts
index 781200500af..125f92237c4 100644
--- a/src/vs/workbench/browser/contextkeys.ts
+++ b/src/vs/workbench/browser/contextkeys.ts
@@ -18,7 +18,8 @@ import { WorkbenchState, IWorkspaceContextService } from 'vs/platform/workspace/
import { SideBarVisibleContext } from 'vs/workbench/common/viewlet';
import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService';
import { PanelAlignmentContext, PanelMaximizedContext, PanelVisibleContext } from 'vs/workbench/common/panel';
-import { getRemoteName, getVirtualWorkspaceScheme } from 'vs/platform/remote/common/remoteHosts';
+import { getRemoteName } from 'vs/platform/remote/common/remoteHosts';
+import { getVirtualWorkspaceScheme } from 'vs/platform/workspace/common/virtualWorkspace';
import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService';
import { isNative } from 'vs/base/common/platform';
import { IEditorResolverService } from 'vs/workbench/services/editor/common/editorResolverService';
diff --git a/src/vs/workbench/browser/layout.ts b/src/vs/workbench/browser/layout.ts
index 023d21d4968..b8afad55fcd 100644
--- a/src/vs/workbench/browser/layout.ts
+++ b/src/vs/workbench/browser/layout.ts
@@ -45,7 +45,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten
import { ILogService } from 'vs/platform/log/common/log';
import { DeferredPromise, Promises } from 'vs/base/common/async';
import { IBannerService } from 'vs/workbench/services/banner/browser/bannerService';
-import { getVirtualWorkspaceScheme } from 'vs/platform/remote/common/remoteHosts';
+import { getVirtualWorkspaceScheme } from 'vs/platform/workspace/common/virtualWorkspace';
import { Schemas } from 'vs/base/common/network';
import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite';
import { ActivitybarPart } from 'vs/workbench/browser/parts/activitybar/activitybarPart';
diff --git a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts
index 829ea03e13d..a08aee86cf0 100644
--- a/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts
+++ b/src/vs/workbench/browser/parts/titlebar/titlebarPart.ts
@@ -42,7 +42,7 @@ import { IProductService } from 'vs/platform/product/common/productService';
import { Schemas } from 'vs/base/common/network';
import { withNullAsUndefined } from 'vs/base/common/types';
import { Codicon } from 'vs/base/common/codicons';
-import { getVirtualWorkspaceLocation } from 'vs/platform/remote/common/remoteHosts';
+import { getVirtualWorkspaceLocation } from 'vs/platform/workspace/common/virtualWorkspace';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { DropdownMenuActionViewItem } from 'vs/base/browser/ui/dropdown/dropdownActionViewItem';
import { AnchorAlignment } from 'vs/base/browser/ui/contextview/contextview';
diff --git a/src/vs/workbench/contrib/audioCues/browser/audioCueContribution.ts b/src/vs/workbench/contrib/audioCues/browser/audioCueContribution.ts
index 649cfd1e0dc..8ed9f6087ca 100644
--- a/src/vs/workbench/contrib/audioCues/browser/audioCueContribution.ts
+++ b/src/vs/workbench/contrib/audioCues/browser/audioCueContribution.ts
@@ -133,7 +133,7 @@ export class AudioCueContribution extends DisposableStore implements IWorkbenchC
hadMarker = hasMarker;
const regionAtLine = foldingModel?.getRegionAtLine(lineNumber);
- const hasFolding = regionAtLine?.startLineNumber === lineNumber;
+ const hasFolding = !regionAtLine ? false : regionAtLine.isCollapsed && regionAtLine.startLineNumber === lineNumber;
if (hasFolding && !hadFoldedArea) {
this.handleFoldedAreasOnLine();
}
diff --git a/src/vs/workbench/contrib/audioCues/browser/media/break.opus b/src/vs/workbench/contrib/audioCues/browser/media/break.opus
index e025dd7e784..a500eec2fb8 100644
--- a/src/vs/workbench/contrib/audioCues/browser/media/break.opus
+++ b/src/vs/workbench/contrib/audioCues/browser/media/break.opus
Binary files differ
diff --git a/src/vs/workbench/contrib/audioCues/browser/media/error.opus b/src/vs/workbench/contrib/audioCues/browser/media/error.opus
index eade1900ece..9f0170086f9 100644
--- a/src/vs/workbench/contrib/audioCues/browser/media/error.opus
+++ b/src/vs/workbench/contrib/audioCues/browser/media/error.opus
Binary files differ
diff --git a/src/vs/workbench/contrib/audioCues/browser/media/foldedAreas.opus b/src/vs/workbench/contrib/audioCues/browser/media/foldedAreas.opus
index f840aaa2953..c5be7c1b84c 100644
--- a/src/vs/workbench/contrib/audioCues/browser/media/foldedAreas.opus
+++ b/src/vs/workbench/contrib/audioCues/browser/media/foldedAreas.opus
Binary files differ
diff --git a/src/vs/workbench/contrib/debug/browser/linkDetector.ts b/src/vs/workbench/contrib/debug/browser/linkDetector.ts
index 7f30bb7ec46..cab19a5d584 100644
--- a/src/vs/workbench/contrib/debug/browser/linkDetector.ts
+++ b/src/vs/workbench/contrib/debug/browser/linkDetector.ts
@@ -16,7 +16,7 @@ import { IPathService } from 'vs/workbench/services/path/common/pathService';
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { KeyCode } from 'vs/base/common/keyCodes';
import { localize } from 'vs/nls';
-import { ITunnelService } from 'vs/platform/remote/common/tunnel';
+import { ITunnelService } from 'vs/platform/tunnel/common/tunnel';
const CONTROL_CODES = '\\u0000-\\u0020\\u007f-\\u009f';
const WEB_LINK_REGEX = new RegExp('(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\\/\\/|data:|www\\.)[^\\s' + CONTROL_CODES + '"]{2,}[^\\s' + CONTROL_CODES + '"\')}\\],:;.!?]', 'ug');
diff --git a/src/vs/workbench/contrib/debug/test/browser/linkDetector.test.ts b/src/vs/workbench/contrib/debug/test/browser/linkDetector.test.ts
index f95af99c8c8..3e7ed14e6f8 100644
--- a/src/vs/workbench/contrib/debug/test/browser/linkDetector.test.ts
+++ b/src/vs/workbench/contrib/debug/test/browser/linkDetector.test.ts
@@ -10,7 +10,7 @@ import { LinkDetector } from 'vs/workbench/contrib/debug/browser/linkDetector';
import { isWindows } from 'vs/base/common/platform';
import { WorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { URI } from 'vs/base/common/uri';
-import { ITunnelService } from 'vs/platform/remote/common/tunnel';
+import { ITunnelService } from 'vs/platform/tunnel/common/tunnel';
import { DisposableStore } from 'vs/base/common/lifecycle';
suite('Debug - Link Detector', () => {
diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts
index a639ecb32c4..f83f656ca0a 100644
--- a/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts
+++ b/src/vs/workbench/contrib/extensions/browser/extensionsActions.ts
@@ -59,7 +59,7 @@ import { errorIcon, infoIcon, manageExtensionIcon, syncEnabledIcon, syncIgnoredI
import { isIOS, isWeb } from 'vs/base/common/platform';
import { IExtensionManifestPropertiesService } from 'vs/workbench/services/extensions/common/extensionManifestPropertiesService';
import { IWorkspaceTrustEnablementService, IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust';
-import { isVirtualWorkspace } from 'vs/platform/remote/common/remoteHosts';
+import { isVirtualWorkspace } from 'vs/platform/workspace/common/virtualWorkspace';
import { escapeMarkdownSyntaxTokens, IMarkdownString, MarkdownString } from 'vs/base/common/htmlContent';
import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite';
import { ViewContainerLocation } from 'vs/workbench/common/views';
diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts
index 5c5ab4a29ae..edd8b3cda81 100644
--- a/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts
+++ b/src/vs/workbench/contrib/extensions/browser/extensionsViews.ts
@@ -49,7 +49,7 @@ import { IPreferencesService } from 'vs/workbench/services/preferences/common/pr
import { IListAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { IExtensionManifestPropertiesService } from 'vs/workbench/services/extensions/common/extensionManifestPropertiesService';
-import { isVirtualWorkspace } from 'vs/platform/remote/common/remoteHosts';
+import { isVirtualWorkspace } from 'vs/platform/workspace/common/virtualWorkspace';
import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust';
import { IWorkbenchLayoutService, Position } from 'vs/workbench/services/layout/browser/layoutService';
import { HoverPosition } from 'vs/base/browser/ui/hover/hoverWidget';
diff --git a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts
index a5a52385a93..b7d6e54158c 100644
--- a/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts
+++ b/src/vs/workbench/contrib/extensions/test/electron-browser/extensionsWorkbenchService.test.ts
@@ -34,7 +34,8 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
import { NativeURLService } from 'vs/platform/url/common/urlService';
import { URI } from 'vs/base/common/uri';
import { CancellationToken } from 'vs/base/common/cancellation';
-import { ExtensionType, IExtension, ExtensionKind } from 'vs/platform/extensions/common/extensions';
+import { ExtensionType, IExtension } from 'vs/platform/extensions/common/extensions';
+import { ExtensionKind } from 'vs/platform/environment/common/environment';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { RemoteAgentService } from 'vs/workbench/services/remote/electron-sandbox/remoteAgentService';
import { ISharedProcessService } from 'vs/platform/ipc/electron-sandbox/services';
diff --git a/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts b/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts
index 1021166c131..e4748579291 100644
--- a/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts
+++ b/src/vs/workbench/contrib/remote/browser/remoteExplorer.ts
@@ -21,7 +21,7 @@ import { ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal
import { IDebugService } from 'vs/workbench/contrib/debug/common/debug';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { isWeb, OperatingSystem } from 'vs/base/common/platform';
-import { isPortPrivileged, ITunnelService, RemoteTunnel } from 'vs/platform/remote/common/tunnel';
+import { isPortPrivileged, ITunnelService, RemoteTunnel } from 'vs/platform/tunnel/common/tunnel';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer';
import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity';
diff --git a/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts b/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts
index 711097dba4a..8c7b07b6354 100644
--- a/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts
+++ b/src/vs/workbench/contrib/remote/browser/remoteIndicator.ts
@@ -25,7 +25,8 @@ import { isWeb } from 'vs/base/common/platform';
import { once } from 'vs/base/common/functional';
import { truncate } from 'vs/base/common/strings';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
-import { getRemoteName, getVirtualWorkspaceLocation } from 'vs/platform/remote/common/remoteHosts';
+import { getRemoteName } from 'vs/platform/remote/common/remoteHosts';
+import { getVirtualWorkspaceLocation } from 'vs/platform/workspace/common/virtualWorkspace';
import { getCodiconAriaLabel } from 'vs/base/common/codicons';
import { ILogService } from 'vs/platform/log/common/log';
import { ReloadWindowAction } from 'vs/workbench/browser/actions/windowActions';
diff --git a/src/vs/workbench/contrib/remote/browser/tunnelView.ts b/src/vs/workbench/contrib/remote/browser/tunnelView.ts
index 3d9236aa451..298de73ffbd 100644
--- a/src/vs/workbench/contrib/remote/browser/tunnelView.ts
+++ b/src/vs/workbench/contrib/remote/browser/tunnelView.ts
@@ -34,7 +34,8 @@ import { IThemeService, registerThemingParticipant, ThemeIcon } from 'vs/platfor
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPane';
import { URI } from 'vs/base/common/uri';
-import { isAllInterfaces, isLocalhost, isPortPrivileged, ITunnelService, RemoteTunnel, TunnelPrivacy, TunnelPrivacyId, TunnelProtocol } from 'vs/platform/remote/common/tunnel';
+import { isAllInterfaces, isLocalhost, isPortPrivileged, ITunnelService, RemoteTunnel, TunnelPrivacyId, TunnelProtocol } from 'vs/platform/tunnel/common/tunnel';
+import { TunnelPrivacy } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
diff --git a/src/vs/workbench/contrib/remote/common/tunnelFactory.ts b/src/vs/workbench/contrib/remote/common/tunnelFactory.ts
index d07daa8f4af..135231c51f6 100644
--- a/src/vs/workbench/contrib/remote/common/tunnelFactory.ts
+++ b/src/vs/workbench/contrib/remote/common/tunnelFactory.ts
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
-import { ITunnelService, TunnelOptions, RemoteTunnel, TunnelCreationOptions, ITunnel, TunnelProtocol, TunnelPrivacyId } from 'vs/platform/remote/common/tunnel';
+import { ITunnelService, TunnelOptions, RemoteTunnel, TunnelCreationOptions, ITunnel, TunnelProtocol, TunnelPrivacyId } from 'vs/platform/tunnel/common/tunnel';
import { Disposable } from 'vs/base/common/lifecycle';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
diff --git a/src/vs/workbench/contrib/scm/browser/media/scm.css b/src/vs/workbench/contrib/scm/browser/media/scm.css
index be9ec9e5944..88664cdd502 100644
--- a/src/vs/workbench/contrib/scm/browser/media/scm.css
+++ b/src/vs/workbench/contrib/scm/browser/media/scm.css
@@ -198,19 +198,43 @@
}
.scm-view .button-container {
- padding-left: 11px;
- height: 100%;
display: flex;
+ height: 100%;
+ padding-left: 11px;
align-items: center;
}
+.scm-view .button-container > .monaco-description-button {
+ flex-direction: row;
+ flex-wrap: wrap;
+ height: 30px;
+ overflow: hidden;
+}
+
+.scm-view .button-container > .monaco-description-button > .monaco-button-label {
+ flex-grow: 1;
+ width: 0;
+ overflow: hidden;
+}
+
+.scm-view .button-container > .monaco-description-button > .monaco-button-description {
+ flex-basis: 100%;
+}
+
+.scm-view .button-container > .monaco-description-button > .monaco-button-label,
+.scm-view .button-container > .monaco-description-button > .monaco-button-description {
+ font-style: inherit;
+}
+
.scm-view .button-container .codicon.codicon-cloud-upload,
.scm-view .button-container .codicon.codicon-sync {
+ line-height: 22px;
margin: 0 0.4em 0 0;
}
.scm-view .button-container .codicon.codicon-arrow-up,
.scm-view .button-container .codicon.codicon-arrow-down {
+ line-height: 22px;
font-size: small !important;
margin: 0 0.2em 0 0;
}
diff --git a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts
index d50fe7dd7cc..bb666ecdda5 100644
--- a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts
+++ b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts
@@ -10,7 +10,7 @@ import { IDisposable, Disposable, DisposableStore, combinedDisposable, dispose,
import { ViewPane, IViewPaneOptions, ViewAction } from 'vs/workbench/browser/parts/views/viewPane';
import { append, $, Dimension, asCSSUrl, trackFocus, clearNode } from 'vs/base/browser/dom';
import { IListVirtualDelegate, IIdentityProvider } from 'vs/base/browser/ui/list/list';
-import { ISCMResourceGroup, ISCMResource, InputValidationType, ISCMRepository, ISCMInput, IInputValidation, ISCMViewService, ISCMViewVisibleRepositoryChangeEvent, ISCMService, SCMInputChangeReason, VIEW_PANE_ID, ISCMActionButton } from 'vs/workbench/contrib/scm/common/scm';
+import { ISCMResourceGroup, ISCMResource, InputValidationType, ISCMRepository, ISCMInput, IInputValidation, ISCMViewService, ISCMViewVisibleRepositoryChangeEvent, ISCMService, SCMInputChangeReason, VIEW_PANE_ID, ISCMActionButton, ISCMActionButtonDescriptor } from 'vs/workbench/contrib/scm/common/scm';
import { ResourceLabels, IResourceLabel, IFileLabelOptions } from 'vs/workbench/browser/labels';
import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
@@ -82,8 +82,7 @@ import { API_OPEN_DIFF_EDITOR_COMMAND_ID, API_OPEN_EDITOR_COMMAND_ID } from 'vs/
import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { MarkdownRenderer } from 'vs/editor/browser/core/markdownRenderer';
-import { Button } from 'vs/base/browser/ui/button/button';
-import { Command } from 'vs/editor/common/languages';
+import { Button, ButtonWithDescription } from 'vs/base/browser/ui/button/button';
import { INotificationService } from 'vs/platform/notification/common/notification';
type TreeElement = ISCMRepository | ISCMInput | ISCMActionButton | ISCMResourceGroup | IResourceNode<ISCMResource, ISCMResourceGroup> | ISCMResource;
@@ -95,7 +94,7 @@ interface ISCMLayout {
}
interface ActionButtonTemplate {
- readonly actionButton: ScmActionButton;
+ readonly actionButton: SCMActionButton;
disposable: IDisposable;
readonly templateDisposable: IDisposable;
}
@@ -120,7 +119,7 @@ class ActionButtonRenderer implements ICompressibleTreeRenderer<ISCMActionButton
container.parentElement!.parentElement!.classList.add('force-no-hover');
const buttonContainer = append(container, $('.button-container'));
- const actionButton = new ScmActionButton(buttonContainer, this.commandService, this.themeService, this.notificationService);
+ const actionButton = new SCMActionButton(buttonContainer, this.commandService, this.themeService, this.notificationService);
return { actionButton, disposable: Disposable.None, templateDisposable: actionButton };
}
@@ -832,7 +831,7 @@ export class SCMAccessibilityProvider implements IListAccessibilityProvider<Tree
} else if (isSCMInput(element)) {
return localize('input', "Source Control Input");
} else if (isSCMActionButton(element)) {
- return element.button?.title ?? '';
+ return element.button?.command.title ?? '';
} else if (isSCMResourceGroup(element)) {
return element.label;
} else {
@@ -2479,8 +2478,8 @@ registerThemingParticipant((theme, collector) => {
}
});
-export class ScmActionButton implements IDisposable {
- private button: Button | undefined;
+export class SCMActionButton implements IDisposable {
+ private button: Button | ButtonWithDescription | undefined;
private readonly disposables = new MutableDisposable<DisposableStore>();
constructor(
@@ -2495,19 +2494,26 @@ export class ScmActionButton implements IDisposable {
this.disposables?.dispose();
}
-
- setButton(button: Command | undefined): void {
+ setButton(button: ISCMActionButtonDescriptor | undefined): void {
// Clear old button
this.clear();
if (!button) {
return;
}
- this.button = new Button(this.container, { title: button.tooltip, supportIcons: true });
- this.button.label = button.title;
+ if (button.description) {
+ // ButtonWithDescription
+ this.button = new ButtonWithDescription(this.container, { supportIcons: true });
+ (this.button as ButtonWithDescription).description = button.description;
+ } else {
+ // Button
+ this.button = new Button(this.container, { supportIcons: true });
+ }
+
+ this.button.label = button.command.title;
this.button.onDidClick(async () => {
try {
- await this.commandService.executeCommand(button!.id, ...(button!.arguments || []));
+ await this.commandService.executeCommand(button.command.id, ...(button.command.arguments || []));
} catch (ex) {
this.notificationService.error(ex);
}
diff --git a/src/vs/workbench/contrib/scm/common/scm.ts b/src/vs/workbench/contrib/scm/common/scm.ts
index 9ecf3c32001..f69a3186779 100644
--- a/src/vs/workbench/contrib/scm/common/scm.ts
+++ b/src/vs/workbench/contrib/scm/common/scm.ts
@@ -65,7 +65,7 @@ export interface ISCMProvider extends IDisposable {
readonly onDidChangeCommitTemplate: Event<string>;
readonly onDidChangeStatusBarCommands?: Event<Command[]>;
readonly acceptInputCommand?: Command;
- readonly actionButton?: Command;
+ readonly actionButton?: ISCMActionButtonDescriptor;
readonly statusBarCommands?: Command[];
readonly onDidChange: Event<void>;
@@ -97,10 +97,15 @@ export interface ISCMInputChangeEvent {
readonly reason?: SCMInputChangeReason;
}
+export interface ISCMActionButtonDescriptor {
+ command: Command;
+ description?: string
+}
+
export interface ISCMActionButton {
readonly type: 'actionButton';
readonly repository: ISCMRepository;
- readonly button?: Command;
+ readonly button?: ISCMActionButtonDescriptor;
}
export interface ISCMInput {
diff --git a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts
index 581d17f807f..f43bad7b5d3 100644
--- a/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts
+++ b/src/vs/workbench/contrib/tasks/browser/abstractTaskService.ts
@@ -3013,7 +3013,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
switch (taskSource) {
case TaskSourceKind.User: tasksExistInFile = this.configHasTasks(configValue.userValue); target = ConfigurationTarget.USER; break;
case TaskSourceKind.WorkspaceFile: tasksExistInFile = this.configHasTasks(configValue.workspaceValue); target = ConfigurationTarget.WORKSPACE; break;
- default: tasksExistInFile = this.configHasTasks(configValue.value); target = ConfigurationTarget.WORKSPACE_FOLDER;
+ default: tasksExistInFile = this.configHasTasks(configValue.workspaceFolderValue); target = ConfigurationTarget.WORKSPACE_FOLDER;
}
let content;
if (!tasksExistInFile) {
@@ -3156,7 +3156,7 @@ export abstract class AbstractTaskService extends Disposable implements ITaskSer
}
}
}
- if (needsCreateOrOpen) {
+ if (needsCreateOrOpen || (taskMap.get(USER_TASKS_GROUP_KEY).length === tasks.length)) {
let label = stats[0] !== undefined ? openLabel : createLabel;
if (entries.length) {
entries.push({ type: 'separator' });
diff --git a/src/vs/workbench/contrib/terminal/browser/links/terminalBaseLinkProvider.ts b/src/vs/workbench/contrib/terminal/browser/links/terminalBaseLinkProvider.ts
index 3adccc7f5c2..28d61c962d0 100644
--- a/src/vs/workbench/contrib/terminal/browser/links/terminalBaseLinkProvider.ts
+++ b/src/vs/workbench/contrib/terminal/browser/links/terminalBaseLinkProvider.ts
@@ -3,13 +3,13 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import type { ILinkProvider, ILink } from 'xterm';
+import type { ILinkProvider } from 'xterm';
import { TerminalLink } from 'vs/workbench/contrib/terminal/browser/links/terminalLink';
export abstract class TerminalBaseLinkProvider implements ILinkProvider {
private _activeLinks: TerminalLink[] | undefined;
- async provideLinks(bufferLineNumber: number, callback: (links: ILink[] | undefined) => void): Promise<void> {
+ async provideLinks(bufferLineNumber: number, callback: (links: TerminalLink[] | undefined) => void): Promise<void> {
this._activeLinks?.forEach(l => l.dispose);
this._activeLinks = await this._provideLinks(bufferLineNumber);
callback(this._activeLinks);
diff --git a/src/vs/workbench/contrib/terminal/browser/links/terminalLink.ts b/src/vs/workbench/contrib/terminal/browser/links/terminalLink.ts
index e1421365a86..3815b4d2498 100644
--- a/src/vs/workbench/contrib/terminal/browser/links/terminalLink.ts
+++ b/src/vs/workbench/contrib/terminal/browser/links/terminalLink.ts
@@ -19,6 +19,7 @@ export const FOLDER_NOT_IN_WORKSPACE_LABEL = localize('openFolder', 'Open folder
export class TerminalLink extends DisposableStore implements ILink {
decorations: ILinkDecorations;
+ asyncActivate: Promise<void> | undefined;
private _tooltipScheduler: RunOnceScheduler | undefined;
private _hoverListeners: DisposableStore | undefined;
@@ -26,12 +27,14 @@ export class TerminalLink extends DisposableStore implements ILink {
private readonly _onInvalidated = new Emitter<void>();
get onInvalidated(): Event<void> { return this._onInvalidated.event; }
+
+
constructor(
private readonly _xterm: Terminal,
readonly range: IBufferRange,
readonly text: string,
private readonly _viewportY: number,
- private readonly _activateCallback: (event: MouseEvent | undefined, uri: string) => void,
+ private readonly _activateCallback: (event: MouseEvent | undefined, uri: string) => Promise<void>,
private readonly _tooltipCallback: (link: TerminalLink, viewportRange: IViewportRange, modifierDownCallback?: () => void, modifierUpCallback?: () => void) => void,
private readonly _isHighConfidenceLink: boolean,
readonly label: string | undefined,
@@ -53,7 +56,9 @@ export class TerminalLink extends DisposableStore implements ILink {
}
activate(event: MouseEvent | undefined, text: string): void {
- this._activateCallback(event, text);
+ // Trigger the xterm.js callback synchronously but track the promise resolution so we can
+ // use it in tests
+ this.asyncActivate = this._activateCallback(event, text);
}
hover(event: MouseEvent, text: string): void {
diff --git a/src/vs/workbench/contrib/terminal/browser/links/terminalLinkManager.ts b/src/vs/workbench/contrib/terminal/browser/links/terminalLinkManager.ts
index 811243cb7da..88906a8e3db 100644
--- a/src/vs/workbench/contrib/terminal/browser/links/terminalLinkManager.ts
+++ b/src/vs/workbench/contrib/terminal/browser/links/terminalLinkManager.ts
@@ -27,7 +27,7 @@ import { IXtermCore } from 'vs/workbench/contrib/terminal/browser/xterm-private'
import { TerminalHover, ILinkHoverTargetOptions } from 'vs/workbench/contrib/terminal/browser/widgets/terminalHoverWidget';
import { TerminalLink } from 'vs/workbench/contrib/terminal/browser/links/terminalLink';
import { TerminalExternalLinkProviderAdapter } from 'vs/workbench/contrib/terminal/browser/links/terminalExternalLinkProviderAdapter';
-import { ITunnelService } from 'vs/platform/remote/common/tunnel';
+import { ITunnelService } from 'vs/platform/tunnel/common/tunnel';
import { XtermTerminal } from 'vs/workbench/contrib/terminal/browser/xterm/xtermTerminal';
import { TerminalCapabilityStoreMultiplexer } from 'vs/workbench/contrib/terminal/common/capabilities/terminalCapabilityStore';
diff --git a/src/vs/workbench/contrib/terminal/browser/links/terminalProtocolLinkProvider.ts b/src/vs/workbench/contrib/terminal/browser/links/terminalProtocolLinkProvider.ts
index 137cfbf6fda..226b0a48aa9 100644
--- a/src/vs/workbench/contrib/terminal/browser/links/terminalProtocolLinkProvider.ts
+++ b/src/vs/workbench/contrib/terminal/browser/links/terminalProtocolLinkProvider.ts
@@ -22,7 +22,7 @@ export class TerminalProtocolLinkProvider extends TerminalBaseLinkProvider {
static id: string = 'TerminalProtocolLinkProvider';
constructor(
private readonly _xterm: Terminal,
- private readonly _activateCallback: (event: MouseEvent | undefined, uri: string) => void,
+ private readonly _activateCallback: (event: MouseEvent | undefined, uri: string) => Promise<void>,
private readonly _wrapLinkHandler: (handler: (event: MouseEvent | undefined, link: string) => void) => XtermLinkMatcherHandler,
private readonly _tooltipCallback: (link: TerminalLink, viewportRange: IViewportRange, modifierDownCallback?: () => void, modifierUpCallback?: () => void) => void,
private readonly _validationCallback: (link: string, callback: (result: { uri: URI, isDirectory: boolean } | undefined) => void) => void,
diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.ts b/src/vs/workbench/contrib/terminal/browser/terminal.ts
index 95cfb3064a6..2968201665a 100644
--- a/src/vs/workbench/contrib/terminal/browser/terminal.ts
+++ b/src/vs/workbench/contrib/terminal/browser/terminal.ts
@@ -17,8 +17,9 @@ import { DeserializedTerminalEditorInput } from 'vs/workbench/contrib/terminal/b
import { TerminalEditorInput } from 'vs/workbench/contrib/terminal/browser/terminalEditorInput';
import { EditorGroupColumn } from 'vs/workbench/services/editor/common/editorGroupColumn';
import { IKeyMods } from 'vs/platform/quickinput/common/quickInput';
-import { IMarker } from 'xterm';
+import { ILink, IMarker } from 'xterm';
import { ITerminalCapabilityStore } from 'vs/workbench/contrib/terminal/common/capabilities/capabilities';
+import { IDetectedLinks, TerminalLinkManager } from 'vs/workbench/contrib/terminal/browser/links/terminalLinkManager';
export const ITerminalService = createDecorator<ITerminalService>('terminalService');
export const ITerminalEditorService = createDecorator<ITerminalEditorService>('terminalEditorService');
@@ -884,6 +885,16 @@ export interface IXtermTerminal {
* When process capabilites are updated, update the command tracker
*/
upgradeCommandTracker(): void;
+
+ /*
+ * Activates the most recent link for the type
+ */
+ openRecentLink(linkManager: TerminalLinkManager, type: 'file' | 'web'): Promise<ILink | undefined>;
+
+ /*
+ * Gets all of the links
+ */
+ getLinks(linkManager: TerminalLinkManager): Promise<IDetectedLinks>;
}
export interface IRequestAddInstanceToGroupEvent {
diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
index 7d354a8ba8e..de242332542 100644
--- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
+++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
@@ -27,9 +27,9 @@ import { ITerminalProcessManager, ProcessState, TERMINAL_VIEW_ID, INavigationMod
import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper';
import { IDetectedLinks, TerminalLinkManager } from 'vs/workbench/contrib/terminal/browser/links/terminalLinkManager';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
-import { ITerminalInstance, ITerminalExternalLinkProvider, IRequestAddInstanceToGroupEvent, TerminalCommand, TerminalLinkQuickPickEvent } from 'vs/workbench/contrib/terminal/browser/terminal';
+import { ITerminalInstance, ITerminalExternalLinkProvider, IRequestAddInstanceToGroupEvent, TerminalCommand } from 'vs/workbench/contrib/terminal/browser/terminal';
import { TerminalProcessManager } from 'vs/workbench/contrib/terminal/browser/terminalProcessManager';
-import type { Terminal as XTermTerminal, ITerminalAddon, ILink } from 'xterm';
+import type { Terminal as XTermTerminal, ITerminalAddon } from 'xterm';
import { NavigationModeAddon } from 'vs/workbench/contrib/terminal/browser/xterm/navigationModeAddon';
import { IViewsService, IViewDescriptorService, ViewContainerLocation } from 'vs/workbench/common/views';
import { EnvironmentVariableInfoWidget } from 'vs/workbench/contrib/terminal/browser/widgets/environmentVariableInfoWidget';
@@ -678,26 +678,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
if (!this.xterm) {
throw new Error('no xterm');
}
- const wordResults: ILink[] = [];
- const webResults: ILink[] = [];
- const fileResults: ILink[] = [];
-
- for (let i = this.xterm.raw.buffer.active.length - 1; i >= this.xterm.raw.buffer.active.viewportY; i--) {
- const links = await this._linkManager.getLinks(i);
- if (links) {
- const { wordLinks, webLinks, fileLinks } = links;
- if (wordLinks && wordLinks.length) {
- wordResults!.push(...wordLinks.reverse());
- }
- if (webLinks && webLinks.length) {
- webResults!.push(...webLinks.reverse());
- }
- if (fileLinks && fileLinks.length) {
- fileResults!.push(...fileLinks.reverse());
- }
- }
- }
- return { wordLinks: wordResults, webLinks: webResults, fileLinks: fileResults };
+ return this.xterm.getLinks(this._linkManager);
}
async openRecentLink(type: 'file' | 'web'): Promise<void> {
@@ -707,19 +688,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance {
if (!this.xterm) {
throw new Error('no xterm');
}
-
- let links;
- let i = this.xterm.raw.buffer.active.length;
- while ((!links || links.length === 0) && i >= this.xterm.raw.buffer.active.viewportY) {
- links = await this._linkManager.getLinksForType(i, type);
- i--;
- }
-
- if (!links || links.length < 1) {
- return;
- }
- const event = new TerminalLinkQuickPickEvent(dom.EventType.CLICK);
- links[0].activate(event, links[0].text);
+ this.xterm.openRecentLink(this._linkManager, type);
}
async runRecent(type: 'command' | 'cwd'): Promise<void> {
diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts
index 09527bac68f..7e25eb2c1df 100644
--- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts
+++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts
@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import type { IBuffer, ITheme, RendererType, Terminal as RawXtermTerminal } from 'xterm';
+import type { IBuffer, ILink, ITheme, RendererType, Terminal as RawXtermTerminal } from 'xterm';
import type { ISearchOptions, SearchAddon as SearchAddonType } from 'xterm-addon-search';
import type { Unicode11Addon as Unicode11AddonType } from 'xterm-addon-unicode11';
import type { WebglAddon as WebglAddonType } from 'xterm-addon-webgl';
@@ -15,7 +15,7 @@ import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
import { TerminalCapability, TerminalLocation, TerminalSettingId } from 'vs/platform/terminal/common/terminal';
import { IShellIntegration, ITerminalFont, TERMINAL_VIEW_ID } from 'vs/workbench/contrib/terminal/common/terminal';
import { isSafari } from 'vs/base/browser/browser';
-import { ICommandTracker, IXtermTerminal } from 'vs/workbench/contrib/terminal/browser/terminal';
+import { ICommandTracker, IXtermTerminal, TerminalLinkQuickPickEvent } from 'vs/workbench/contrib/terminal/browser/terminal';
import { ILogService } from 'vs/platform/log/common/log';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { TerminalStorageKeys } from 'vs/workbench/contrib/terminal/common/terminalStorageKeys';
@@ -31,6 +31,8 @@ import { Color } from 'vs/base/common/color';
import { ShellIntegrationAddon, ShellIntegrationInteraction } from 'vs/workbench/contrib/terminal/browser/xterm/shellIntegrationAddon';
import { CognisantCommandTrackerAddon } from 'vs/workbench/contrib/terminal/browser/xterm/cognisantCommandTrackerAddon';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
+import { IDetectedLinks, TerminalLinkManager } from 'vs/workbench/contrib/terminal/browser/links/terminalLinkManager';
+import { EventType } from 'vs/base/browser/dom';
// How long in milliseconds should an average frame take to render for a notification to appear
// which suggests the fallback DOM-based renderer
@@ -117,8 +119,8 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal {
macOptionClickForcesSelection: config.macOptionClickForcesSelection,
rightClickSelectsWord: config.rightClickBehavior === 'selectWord',
fastScrollModifier: 'alt',
- fastScrollSensitivity: editorOptions.fastScrollSensitivity,
- scrollSensitivity: editorOptions.mouseWheelScrollSensitivity,
+ fastScrollSensitivity: config.fastScrollSensitivity,
+ scrollSensitivity: config.mouseWheelScrollSensitivity,
rendererType: this._getBuiltInXtermRenderer(config.gpuAcceleration, XtermTerminal._suggestedRendererType),
wordSeparator: config.wordSeparators
}));
@@ -169,6 +171,45 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal {
}
+ async getLinks(linkManager: TerminalLinkManager): Promise<IDetectedLinks> {
+ const wordResults: ILink[] = [];
+ const webResults: ILink[] = [];
+ const fileResults: ILink[] = [];
+
+ for (let i = this.raw.buffer.active.length - 1; i >= this.raw.buffer.active.viewportY; i--) {
+ const links = await linkManager.getLinks(i);
+ if (links) {
+ const { wordLinks, webLinks, fileLinks } = links;
+ if (wordLinks && wordLinks.length) {
+ wordResults.push(...wordLinks.reverse());
+ }
+ if (webLinks && webLinks.length) {
+ webResults.push(...webLinks.reverse());
+ }
+ if (fileLinks && fileLinks.length) {
+ fileResults.push(...fileLinks.reverse());
+ }
+ }
+ }
+ return { webLinks: webResults, fileLinks: fileResults, wordLinks: wordResults };
+ }
+
+ async openRecentLink(linkManager: TerminalLinkManager, type: 'file' | 'web'): Promise<ILink | undefined> {
+ let links;
+ let i = this.raw.buffer.active.length;
+ while ((!links || links.length === 0) && i >= this.raw.buffer.active.viewportY) {
+ links = await linkManager.getLinksForType(i, type);
+ i--;
+ }
+
+ if (!links || links.length < 1) {
+ return undefined;
+ }
+ const event = new TerminalLinkQuickPickEvent(EventType.CLICK);
+ links[0].activate(event, links[0].text);
+ return links[0];
+ }
+
upgradeCommandTracker(): void {
if (this._commandTrackerAddon instanceof CognisantCommandTrackerAddon) {
return;
diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts
index 3951db9b09a..f0b99a2a5af 100644
--- a/src/vs/workbench/contrib/terminal/common/terminal.ts
+++ b/src/vs/workbench/contrib/terminal/common/terminal.ts
@@ -40,6 +40,13 @@ export const DEFAULT_FONT_WEIGHT = 'normal';
export const DEFAULT_BOLD_FONT_WEIGHT = 'bold';
export const SUGGESTIONS_FONT_WEIGHT = ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'];
+
+export interface ITerminalLinkActivationResult {
+ source: 'editor' | 'quickpick',
+ link: string
+}
+
+
export const ITerminalProfileResolverService = createDecorator<ITerminalProfileResolverService>('terminalProfileResolverService');
export interface ITerminalProfileResolverService {
readonly _serviceBrand: undefined;
diff --git a/src/vs/workbench/contrib/terminal/test/browser/links/terminalWordLinkProvider.test.ts b/src/vs/workbench/contrib/terminal/test/browser/links/terminalWordLinkProvider.test.ts
index c77c1366a7b..09b5eb33e01 100644
--- a/src/vs/workbench/contrib/terminal/test/browser/links/terminalWordLinkProvider.test.ts
+++ b/src/vs/workbench/contrib/terminal/test/browser/links/terminalWordLinkProvider.test.ts
@@ -4,19 +4,19 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
-import { Terminal, ILink } from 'xterm';
+import { Terminal } from 'xterm';
import { TerminalWordLinkProvider } from 'vs/workbench/contrib/terminal/browser/links/terminalWordLinkProvider';
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IEditorOptions, ITextResourceEditorInput } from 'vs/platform/editor/common/editor';
-import { AbstractLogger, DEFAULT_LOG_LEVEL, ILogger, ILogService, LogLevel, LogService, NullLogService } from 'vs/platform/log/common/log';
+import { ILogService, NullLogService } from 'vs/platform/log/common/log';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
import { IViewDescriptorService } from 'vs/workbench/common/views';
import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper';
-import { ITerminalConfigHelper, ITerminalConfiguration } from 'vs/workbench/contrib/terminal/common/terminal';
+import { ITerminalConfigHelper, ITerminalConfiguration, ITerminalLinkActivationResult } from 'vs/workbench/contrib/terminal/common/terminal';
import { TestContextService, TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
import { TerminalCapabilityStore } from 'vs/workbench/contrib/terminal/common/capabilities/terminalCapabilityStore';
import { XtermTerminal } from 'vs/workbench/contrib/terminal/browser/xterm/xtermTerminal';
@@ -28,6 +28,16 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { XtermLinkMatcherHandler } from 'vs/workbench/contrib/terminal/browser/links/terminalLinkManager';
+import { FileService } from 'vs/platform/files/common/fileService';
+import { IResolveMetadataFileOptions, IFileStatWithMetadata, IResolveFileOptions, IFileStat, IFileService } from 'vs/platform/files/common/files';
+import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
+import { TerminalLinkQuickPickEvent } from 'vs/workbench/contrib/terminal/browser/terminal';
+import { EventType } from 'vs/base/browser/dom';
+import { URI } from 'vs/base/common/uri';
+import { TerminalLink } from 'vs/workbench/contrib/terminal/browser/links/terminalLink';
+import { isWindows } from 'vs/base/common/platform';
+const pathSeparator = isWindows ? '\\' : '/';
+const filePrefix = 'file:' + pathSeparator.repeat(2);
const defaultTerminalConfig: Partial<ITerminalConfiguration> = {
fontFamily: 'monospace',
@@ -41,81 +51,57 @@ const defaultTerminalConfig: Partial<ITerminalConfiguration> = {
wordSeparators: ' ()[]{}\',"`─‘’'
};
+class TestFileService extends FileService {
+ private _files: string[] = [];
+ override async resolve(resource: URI, options: IResolveMetadataFileOptions): Promise<IFileStatWithMetadata>;
+ override async resolve(resource: URI, options?: IResolveFileOptions): Promise<IFileStat>;
+ override async resolve(resource: URI, options?: IResolveFileOptions): Promise<IFileStat> {
+ if (this._files.includes(resource.path)) {
+ return { isFile: true, isDirectory: false, isSymbolicLink: false } as IFileStat;
+ } else {
+ return { isFile: false, isDirectory: false, isSymbolicLink: false } as IFileStat;
+ }
+ }
+ setFiles(files: string[]): void {
+ this._files = files;
+ }
+}
+
class TestCommandTracker extends CognisantCommandTrackerAddon {
private _currentCwd: string | undefined;
override getCwdForLine(y: number): string {
- return this._currentCwd || '';
+ if (!this._currentCwd) {
+ throw new Error('no cwd');
+ }
+ return this._currentCwd;
}
setCwd(cwd: string): void {
this._currentCwd = cwd;
}
}
-class TestLogger extends AbstractLogger implements ILogger {
-
- public logs: string[] = [];
-
- constructor(logLevel: LogLevel = DEFAULT_LOG_LEVEL) {
- super();
- this.setLevel(logLevel);
- }
-
- trace(message: string, ...args: any[]): void {
- if (this.getLevel() <= LogLevel.Trace) {
- this.logs.push(message + JSON.stringify(args));
- }
- }
-
- debug(message: string, ...args: any[]): void {
- if (this.getLevel() <= LogLevel.Debug) {
- this.logs.push(message);
- }
- }
-
- info(message: string, ...args: any[]): void {
- if (this.getLevel() <= LogLevel.Info) {
- this.logs.push(message);
- }
- }
-
- warn(message: string | Error, ...args: any[]): void {
- if (this.getLevel() <= LogLevel.Warning) {
- this.logs.push(message.toString());
- }
- }
-
- error(message: string, ...args: any[]): void {
- if (this.getLevel() <= LogLevel.Error) {
- this.logs.push(message);
- }
- }
-
- critical(message: string, ...args: any[]): void {
- if (this.getLevel() <= LogLevel.Critical) {
- this.logs.push(message);
- }
- }
-
- override dispose(): void { }
- flush(): void { }
-}
class TestXtermTerminal extends XtermTerminal {
- override get commandTracker(): TestCommandTracker { return new TestCommandTracker(new LogService(new TestLogger())); }
+ private _commandTracker = new TestCommandTracker(new NullLogService());
+ override get commandTracker(): TestCommandTracker {
+ return this._commandTracker;
+ }
}
suite('Workbench - TerminalWordLinkProvider', () => {
let instantiationService: TestInstantiationService;
let configurationService: TestConfigurationService;
let themeService: TestThemeService;
+ let fileService: TestFileService;
let viewDescriptorService: TestViewDescriptorService;
let xterm: TestXtermTerminal;
let configHelper: ITerminalConfigHelper;
let capabilities: TerminalCapabilityStore;
- let activateResult: ITerminalLinkActivationResult | undefined;
+ let activationResult: ITerminalLinkActivationResult | undefined;
setup(() => {
instantiationService = new TestInstantiationService();
+ fileService = new TestFileService(new NullLogService());
configurationService = new TestConfigurationService();
instantiationService.stub(IConfigurationService, configurationService);
configurationService = new TestConfigurationService({
@@ -127,29 +113,34 @@ suite('Workbench - TerminalWordLinkProvider', () => {
integrated: defaultTerminalConfig
}
});
+
themeService = new TestThemeService();
viewDescriptorService = new TestViewDescriptorService();
capabilities = new TerminalCapabilityStore();
instantiationService = new TestInstantiationService();
+ instantiationService.stub(IWorkbenchEnvironmentService, {
+ remoteAuthority: undefined
+ } as Partial<IWorkbenchEnvironmentService>);
instantiationService.stub(IConfigurationService, configurationService);
instantiationService.stub(ILogService, new NullLogService());
instantiationService.stub(IStorageService, new TestStorageService());
instantiationService.stub(IThemeService, themeService);
+ instantiationService.stub(IFileService, fileService);
instantiationService.stub(IViewDescriptorService, viewDescriptorService);
instantiationService.stub(IWorkspaceContextService, new TestContextService());
// Allow intercepting link activations
- activateResult = undefined;
+ activationResult = undefined;
instantiationService.stub(IQuickInputService, {
quickAccess: {
show(link: string) {
- activateResult = { link, source: 'quickpick' };
+ activationResult = { link, source: 'quickpick' };
}
}
} as Partial<IQuickInputService>);
instantiationService.stub(IEditorService, {
async openEditor(editor: ITextResourceEditorInput): Promise<any> {
- activateResult = {
+ activationResult = {
source: 'editor',
link: editor.resource?.toString()
};
@@ -161,19 +152,25 @@ suite('Workbench - TerminalWordLinkProvider', () => {
xterm = instantiationService.createInstance(TestXtermTerminal, Terminal, configHelper, 80, 30, TerminalLocation.Panel);
});
- async function assertLink(text: string, expected: { text: string, range: [number, number][], linkActivationResult?: ITerminalLinkActivationResult }[], registerCwdDetectionCapability?: boolean) {
+ async function assertLink(text: string, expected: { text: string, range: [number, number][], linkActivationResult?: ITerminalLinkActivationResult }[], registerCwdDetectionCapability?: boolean, cwd?: string, files?: string[]) {
xterm?.dispose();
xterm = instantiationService.createInstance(TestXtermTerminal, Terminal, configHelper, 80, 30, TerminalLocation.Panel);
+ if (cwd) {
+ xterm.commandTracker.setCwd(cwd);
+ }
if (registerCwdDetectionCapability) {
capabilities = new TerminalCapabilityStore();
capabilities.add(TerminalCapability.CwdDetection, new CwdDetectionCapability());
}
+ if (files) {
+ fileService.setFiles(files);
+ }
// We don't want to cancel the event or anything from the tests so just pass in a wrapped
// link handler that does nothing.
const testWrappedLinkHandler = (handler: (event: MouseEvent | undefined, link: string) => void): XtermLinkMatcherHandler => {
return async (event: MouseEvent | undefined, link: string) => {
- handler(event, link);
+ await handler(event, link);
};
};
const provider: TerminalWordLinkProvider = instantiationService.createInstance(TerminalWordLinkProvider,
@@ -187,16 +184,16 @@ suite('Workbench - TerminalWordLinkProvider', () => {
await new Promise<void>(r => xterm.raw.write(text, r));
// Ensure all links are provided
- const links = (await new Promise<ILink[] | undefined>(r => provider.provideLinks(1, r)))!;
+ const links = (await new Promise<TerminalLink[] | undefined>(r => provider.provideLinks(1, r)))!;
const actualLinks = await Promise.all(links.map(async e => {
- if (registerCwdDetectionCapability) {
- // HACK: Xterm.js works on sync links only but we use async links
- await e.activate(new MouseEvent('click'), e.text);
+ if (capabilities.has(TerminalCapability.CwdDetection)) {
+ e.activate(new TerminalLinkQuickPickEvent(EventType.CLICK), e.text);
+ await e.asyncActivate;
}
return {
text: e.text,
range: e.range,
- activateText: registerCwdDetectionCapability ? activateResult : undefined
+ activationResult
};
}));
@@ -206,7 +203,7 @@ suite('Workbench - TerminalWordLinkProvider', () => {
start: { x: e.range[0][0], y: e.range[0][1] },
end: { x: e.range[1][0], y: e.range[1][1] },
},
- activateText: e.linkActivationResult
+ activationResult: e.linkActivationResult
}));
assert.deepStrictEqual(actualLinks, expectedVerbose);
assert.strictEqual(links.length, expected.length);
@@ -282,13 +279,25 @@ suite('Workbench - TerminalWordLinkProvider', () => {
await assertLink('file:///C:/users/test/file.txt ', [{ range: [[1, 1], [30, 1]], text: 'file:///C:/users/test/file.txt' }]);
await assertLink('file:///C:/users/test/file.txt:1:10 ', [{ range: [[1, 1], [35, 1]], text: 'file:///C:/users/test/file.txt:1:10' }]);
});
- test.skip('should add cwd to link', async () => {
- xterm.commandTracker.setCwd('/Users/home/folder');
- await assertLink('file.txt ', [{ range: [[1, 1], [8, 1]], text: 'file.txt', linkActivationResult: { link: '/Users/home/folder/file.txt', source: 'editor' } }], true);
+ test('should apply the cwd to the link only when the file exists and cwdDetection is enabled', async () => {
+ if (!isWindows) {
+ const { text, cwd, filePath } = generateLinkArgs(['Users', 'home', 'folder']);
+ await assertLink(text, [{ range: [[1, 1], [8, 1]], text, linkActivationResult: { link: filePrefix + filePath, source: 'editor' } }], true, cwd, [filePath]);
+ await assertLink(text, [{ range: [[1, 1], [8, 1]], text, linkActivationResult: { link: text, source: 'quickpick' } }], true, cwd, []);
+ }
+ });
+ test('should not add the cwd to the link when cwdDetection is not enabled', async () => {
+ if (!isWindows) {
+ const { text, cwd, filePath } = generateLinkArgs(['Users', 'home', 'folder']);
+ await assertLink(text, [{ range: [[1, 1], [8, 1]], text, linkActivationResult: undefined }], false, cwd, [filePath]);
+ await assertLink(text, [{ range: [[1, 1], [8, 1]], text, linkActivationResult: undefined }], false, cwd, []);
+ }
});
});
-interface ITerminalLinkActivationResult {
- source: 'editor' | 'quickpick',
- link: string
+function generateLinkArgs(folders: string[]): { text: string, cwd: string, filePath: string } {
+ const cwd = ['', ...folders].join(pathSeparator);
+ const text = 'file.txt';
+ const filePath = [cwd, text].join(pathSeparator);
+ return { text, cwd, filePath };
}
diff --git a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts
index d23fb008882..cec41378d3f 100644
--- a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts
+++ b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts
@@ -3,11 +3,11 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
-import { IEvent, Terminal } from 'xterm';
+import { IEvent, ILink, Terminal } from 'xterm';
import { XtermTerminal } from 'vs/workbench/contrib/terminal/browser/xterm/xtermTerminal';
import { TerminalConfigHelper } from 'vs/workbench/contrib/terminal/browser/terminalConfigHelper';
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
-import { ITerminalConfigHelper, ITerminalConfiguration, TERMINAL_VIEW_ID } from 'vs/workbench/contrib/terminal/common/terminal';
+import { ITerminalConfigHelper, ITerminalConfiguration, ITerminalProcessManager, TERMINAL_VIEW_ID } from 'vs/workbench/contrib/terminal/common/terminal';
import { deepStrictEqual, strictEqual } from 'assert';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
@@ -24,6 +24,9 @@ import { IStorageService } from 'vs/platform/storage/common/storage';
import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
import { isSafari } from 'vs/base/browser/browser';
import { TerminalLocation } from 'vs/platform/terminal/common/terminal';
+import { IDetectedLinks, TerminalLinkManager } from 'vs/workbench/contrib/terminal/browser/links/terminalLinkManager';
+import { ITerminalCapabilityStore } from 'vs/workbench/contrib/terminal/common/capabilities/capabilities';
+import { equals } from 'vs/base/common/objects';
class TestWebglAddon {
static shouldThrow = false;
@@ -41,6 +44,31 @@ class TestWebglAddon {
clearTextureAtlas() { }
}
+class TestLinkManager extends TerminalLinkManager {
+ private _links: Map<number, IDetectedLinks | undefined> = new Map();
+ override async getLinks(y: number): Promise<IDetectedLinks | undefined> {
+ return this._links.get(y);
+ }
+ override async getLinksForType(y: number, type: 'word' | 'web' | 'file'): Promise<ILink[] | undefined> {
+ const linkResult = await this.getLinks(y);
+ if (!linkResult) {
+ return undefined;
+ }
+ const { wordLinks, webLinks, fileLinks } = linkResult;
+ switch (type) {
+ case 'word':
+ return wordLinks;
+ case 'web':
+ return webLinks;
+ case 'file':
+ return fileLinks;
+ }
+ }
+ setLinks(links: Map<number, IDetectedLinks | undefined>): void {
+ this._links = links;
+ }
+}
+
class TestXtermTerminal extends XtermTerminal {
webglAddonPromise: Promise<typeof WebglAddon> = Promise.resolve(TestWebglAddon);
protected override _getWebglAddonConstructor() {
@@ -85,7 +113,7 @@ suite('XtermTerminal', () => {
let configurationService: TestConfigurationService;
let themeService: TestThemeService;
let viewDescriptorService: TestViewDescriptorService;
-
+ let linkManager: TestLinkManager;
let xterm: TestXtermTerminal;
let configHelper: ITerminalConfigHelper;
@@ -111,6 +139,7 @@ suite('XtermTerminal', () => {
configHelper = instantiationService.createInstance(TerminalConfigHelper);
xterm = instantiationService.createInstance(TestXtermTerminal, Terminal, configHelper, 80, 30, TerminalLocation.Panel);
+ linkManager = instantiationService.createInstance(TestLinkManager, xterm, upcastPartial<ITerminalProcessManager>({}), upcastPartial<ITerminalCapabilityStore>({}));
TestWebglAddon.shouldThrow = false;
TestWebglAddon.isEnabled = false;
@@ -269,4 +298,88 @@ suite('XtermTerminal', () => {
strictEqual(TestWebglAddon.isEnabled, false);
});
});
+ suite('getLinks and open recent link', async () => {
+ test('should return no links', async () => {
+ const map: Map<number, IDetectedLinks> = new Map();
+ map.set(0, {});
+ linkManager.setLinks(map);
+ const links = await xterm.getLinks(linkManager);
+ equals(links, { webLinks: [], wordLinks: [], fileLinks: [] });
+ const webLink = await xterm.openRecentLink(linkManager, 'web');
+ strictEqual(webLink, undefined);
+ const fileLink = await xterm.openRecentLink(linkManager, 'file');
+ strictEqual(fileLink, undefined);
+ });
+ test('should return word links in order', async () => {
+ const map: Map<number, IDetectedLinks> = new Map();
+ const link1 = {
+ range: {
+ start: { x: 1, y: 1 }, end: { x: 14, y: 1 }
+ },
+ text: '1_我是学生.txt',
+ activate: () => Promise.resolve('')
+ };
+ const link2 = {
+ range: {
+ start: { x: 1, y: 1 }, end: { x: 14, y: 1 }
+ },
+ text: '2_我是学生.txt',
+ activate: () => Promise.resolve('')
+ };
+ map.set(0, { wordLinks: [link1, link2] });
+ linkManager.setLinks(map);
+ const links = await xterm.getLinks(linkManager);
+ deepStrictEqual(links, { webLinks: [], wordLinks: [link2, link1], fileLinks: [] });
+ const webLink = await xterm.openRecentLink(linkManager, 'web');
+ strictEqual(webLink, undefined);
+ const fileLink = await xterm.openRecentLink(linkManager, 'file');
+ strictEqual(fileLink, undefined);
+ });
+ test('should return web links in order', async () => {
+ const map: Map<number, IDetectedLinks> = new Map();
+ const link1 = {
+ range: { start: { x: 5, y: 1 }, end: { x: 40, y: 1 } },
+ text: 'https://foo.bar/[this is foo site 1]',
+ activate: () => Promise.resolve('')
+ };
+ const link2 = {
+ range: { start: { x: 5, y: 2 }, end: { x: 40, y: 2 } },
+ text: 'https://foo.bar/[this is foo site 2]',
+ activate: () => Promise.resolve('')
+ };
+ map.set(0, { webLinks: [link1, link2] });
+ linkManager.setLinks(map);
+ const links = await xterm.getLinks(linkManager);
+ deepStrictEqual(links, { webLinks: [link2, link1], wordLinks: [], fileLinks: [] });
+ const webLink = await xterm.openRecentLink(linkManager, 'web');
+ strictEqual(webLink, link2);
+ const fileLink = await xterm.openRecentLink(linkManager, 'file');
+ strictEqual(fileLink, undefined);
+ });
+ test('should return file links in order', async () => {
+ const map: Map<number, IDetectedLinks> = new Map();
+ const link1 = {
+ range: { start: { x: 1, y: 1 }, end: { x: 32, y: 1 } },
+ text: 'file:///C:/users/test/file_1.txt',
+ activate: () => Promise.resolve('')
+ };
+ const link2 = {
+ range: { start: { x: 1, y: 2 }, end: { x: 32, y: 2 } },
+ text: 'file:///C:/users/test/file_2.txt',
+ activate: () => Promise.resolve('')
+ };
+ map.set(0, { fileLinks: [link1, link2] });
+ linkManager.setLinks(map);
+ const links = await xterm.getLinks(linkManager);
+ deepStrictEqual(links, { webLinks: [], wordLinks: [], fileLinks: [link2, link1] });
+ const webLink = await xterm.openRecentLink(linkManager, 'web');
+ strictEqual(webLink, undefined);
+ const fileLink = await xterm.openRecentLink(linkManager, 'file');
+ strictEqual(fileLink, link2);
+ });
+ });
});
+
+function upcastPartial<T>(v: Partial<T>): T {
+ return v as T;
+}
diff --git a/src/vs/workbench/contrib/webview/browser/webviewElement.ts b/src/vs/workbench/contrib/webview/browser/webviewElement.ts
index f406a906518..23ee61899a2 100644
--- a/src/vs/workbench/contrib/webview/browser/webviewElement.ts
+++ b/src/vs/workbench/contrib/webview/browser/webviewElement.ts
@@ -27,7 +27,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { ILogService } from 'vs/platform/log/common/log';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver';
-import { ITunnelService } from 'vs/platform/remote/common/tunnel';
+import { ITunnelService } from 'vs/platform/tunnel/common/tunnel';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { WebviewPortMappingManager } from 'vs/platform/webview/common/webviewPortMapping';
import { asWebviewUri, decodeAuthority, webviewGenericCspSource, webviewRootResourceAuthority } from 'vs/workbench/api/common/shared/webview';
diff --git a/src/vs/workbench/contrib/webview/electron-sandbox/webviewElement.ts b/src/vs/workbench/contrib/webview/electron-sandbox/webviewElement.ts
index 56f60d54d3a..86f4e5f5109 100644
--- a/src/vs/workbench/contrib/webview/electron-sandbox/webviewElement.ts
+++ b/src/vs/workbench/contrib/webview/electron-sandbox/webviewElement.ts
@@ -16,7 +16,7 @@ import { ILogService } from 'vs/platform/log/common/log';
import { INativeHostService } from 'vs/platform/native/electron-sandbox/native';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver';
-import { ITunnelService } from 'vs/platform/remote/common/tunnel';
+import { ITunnelService } from 'vs/platform/tunnel/common/tunnel';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { FindInFrameOptions, IWebviewManagerService } from 'vs/platform/webview/common/webviewManagerService';
import { WebviewThemeDataProvider } from 'vs/workbench/contrib/webview/browser/themeing';
diff --git a/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts b/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts
index 2a61fa5e5c7..3db1ea96f72 100644
--- a/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts
+++ b/src/vs/workbench/contrib/workspace/browser/workspace.contribution.ts
@@ -42,7 +42,7 @@ import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storag
import { splitName } from 'vs/base/common/labels';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IBannerItem, IBannerService } from 'vs/workbench/services/banner/browser/bannerService';
-import { isVirtualWorkspace } from 'vs/platform/remote/common/remoteHosts';
+import { isVirtualWorkspace } from 'vs/platform/workspace/common/virtualWorkspace';
import { LIST_WORKSPACE_UNSUPPORTED_EXTENSIONS_COMMAND_ID } from 'vs/workbench/contrib/extensions/common/extensions';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { WORKSPACE_TRUST_SETTING_TAG } from 'vs/workbench/contrib/preferences/common/preferences';
diff --git a/src/vs/workbench/contrib/workspace/browser/workspaceTrustEditor.ts b/src/vs/workbench/contrib/workspace/browser/workspaceTrustEditor.ts
index 405141da521..6997cbeb844 100644
--- a/src/vs/workbench/contrib/workspace/browser/workspaceTrustEditor.ts
+++ b/src/vs/workbench/contrib/workspace/browser/workspaceTrustEditor.ts
@@ -30,7 +30,7 @@ import { ILabelService } from 'vs/platform/label/common/label';
import { WorkbenchTable } from 'vs/platform/list/browser/listService';
import { Link } from 'vs/platform/opener/browser/link';
import { Registry } from 'vs/platform/registry/common/platform';
-import { isVirtualResource, isVirtualWorkspace } from 'vs/platform/remote/common/remoteHosts';
+import { isVirtualResource, isVirtualWorkspace } from 'vs/platform/workspace/common/virtualWorkspace';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { buttonBackground, buttonSecondaryBackground, editorErrorForeground } from 'vs/platform/theme/common/colorRegistry';
diff --git a/src/vs/workbench/contrib/workspaces/browser/workspaces.contribution.ts b/src/vs/workbench/contrib/workspaces/browser/workspaces.contribution.ts
index 8bb7ed829e5..e20024f6c00 100644
--- a/src/vs/workbench/contrib/workspaces/browser/workspaces.contribution.ts
+++ b/src/vs/workbench/contrib/workspaces/browser/workspaces.contribution.ts
@@ -17,7 +17,7 @@ import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
import { hasWorkspaceFileExtension } from 'vs/platform/workspaces/common/workspaces';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
-import { isVirtualWorkspace } from 'vs/platform/remote/common/remoteHosts';
+import { isVirtualWorkspace } from 'vs/platform/workspace/common/virtualWorkspace';
/**
* A workbench contribution that will look for `.code-workspace` files in the root of the
diff --git a/src/vs/workbench/electron-sandbox/window.ts b/src/vs/workbench/electron-sandbox/window.ts
index 8f8135b26fb..763c8d02384 100644
--- a/src/vs/workbench/electron-sandbox/window.ts
+++ b/src/vs/workbench/electron-sandbox/window.ts
@@ -46,7 +46,7 @@ import { Schemas } from 'vs/base/common/network';
import { INativeHostService } from 'vs/platform/native/electron-sandbox/native';
import { posix, dirname } from 'vs/base/common/path';
import { getBaseLabel } from 'vs/base/common/labels';
-import { ITunnelService, extractLocalHostUriMetaDataForPortMapping } from 'vs/platform/remote/common/tunnel';
+import { ITunnelService, extractLocalHostUriMetaDataForPortMapping } from 'vs/platform/tunnel/common/tunnel';
import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService';
import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService';
import { WorkingCopyCapabilities } from 'vs/workbench/services/workingCopy/common/workingCopy';
diff --git a/src/vs/workbench/services/environment/browser/environmentService.ts b/src/vs/workbench/services/environment/browser/environmentService.ts
index c69f4256db6..d34da178155 100644
--- a/src/vs/workbench/services/environment/browser/environmentService.ts
+++ b/src/vs/workbench/services/environment/browser/environmentService.ts
@@ -7,7 +7,7 @@ import { Schemas } from 'vs/base/common/network';
import { joinPath } from 'vs/base/common/resources';
import { URI } from 'vs/base/common/uri';
import { generateUuid } from 'vs/base/common/uuid';
-import { IExtensionHostDebugParams } from 'vs/platform/environment/common/environment';
+import { ExtensionKind, IExtensionHostDebugParams } from 'vs/platform/environment/common/environment';
import { IPath, IWindowConfiguration } from 'vs/platform/windows/common/windows';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import type { IWorkbenchConstructionOptions as IWorkbenchOptions } from 'vs/workbench/workbench.web.api';
@@ -16,7 +16,6 @@ import { memoize } from 'vs/base/common/decorators';
import { onUnexpectedError } from 'vs/base/common/errors';
import { parseLineAndColumnAware } from 'vs/base/common/extpath';
import { LogLevelToString } from 'vs/platform/log/common/log';
-import { ExtensionKind } from 'vs/platform/extensions/common/extensions';
import { isUndefined } from 'vs/base/common/types';
class BrowserWorkbenchConfiguration implements IWindowConfiguration {
diff --git a/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts b/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts
index 12bb00c76e7..8e99812215f 100644
--- a/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts
+++ b/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.ts
@@ -25,7 +25,7 @@ import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IExtensionBisectService } from 'vs/workbench/services/extensionManagement/browser/extensionBisect';
import { IWorkspaceTrustManagementService, IWorkspaceTrustRequestService } from 'vs/platform/workspace/common/workspaceTrust';
import { IExtensionManifestPropertiesService } from 'vs/workbench/services/extensions/common/extensionManifestPropertiesService';
-import { isVirtualWorkspace } from 'vs/platform/remote/common/remoteHosts';
+import { isVirtualWorkspace } from 'vs/platform/workspace/common/virtualWorkspace';
import { ILogService } from 'vs/platform/log/common/log';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
diff --git a/src/vs/workbench/services/extensions/browser/extensionService.ts b/src/vs/workbench/services/extensions/browser/extensionService.ts
index bc46eaf51eb..33c451aad97 100644
--- a/src/vs/workbench/services/extensions/browser/extensionService.ts
+++ b/src/vs/workbench/services/extensions/browser/extensionService.ts
@@ -18,7 +18,8 @@ import { RemoteExtensionHost, IRemoteExtensionHostDataProvider, IRemoteExtension
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { WebWorkerExtensionHost } from 'vs/workbench/services/extensions/browser/webWorkerExtensionHost';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
-import { ExtensionIdentifier, IExtensionDescription, ExtensionKind, IExtension, ExtensionType } from 'vs/platform/extensions/common/extensions';
+import { ExtensionIdentifier, IExtensionDescription, IExtension, ExtensionType } from 'vs/platform/extensions/common/extensions';
+import { ExtensionKind } from 'vs/platform/environment/common/environment';
import { FetchFileSystemProvider } from 'vs/workbench/services/extensions/browser/webWorkerFileSystemProvider';
import { Schemas } from 'vs/base/common/network';
import { DisposableStore } from 'vs/base/common/lifecycle';
diff --git a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts
index 0dcb821c830..6bf5f9d9b0c 100644
--- a/src/vs/workbench/services/extensions/common/abstractExtensionService.ts
+++ b/src/vs/workbench/services/extensions/common/abstractExtensionService.ts
@@ -20,7 +20,8 @@ import { ExtensionMessageCollector, ExtensionPoint, ExtensionsRegistry, IExtensi
import { ExtensionDescriptionRegistry } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry';
import { ResponsiveState } from 'vs/workbench/services/extensions/common/rpcProtocol';
import { createExtensionHostManager, IExtensionHostManager } from 'vs/workbench/services/extensions/common/extensionHostManager';
-import { ExtensionIdentifier, IExtensionDescription, IExtension, ExtensionKind, IExtensionContributions } from 'vs/platform/extensions/common/extensions';
+import { ExtensionIdentifier, IExtensionDescription, IExtension, IExtensionContributions } from 'vs/platform/extensions/common/extensions';
+import { ExtensionKind } from 'vs/platform/environment/common/environment';
import { IFileService } from 'vs/platform/files/common/files';
import { parseExtensionDevOptions } from 'vs/workbench/services/extensions/common/extensionDevOptions';
import { IProductService } from 'vs/platform/product/common/productService';
diff --git a/src/vs/workbench/services/extensions/common/extensionManifestPropertiesService.ts b/src/vs/workbench/services/extensions/common/extensionManifestPropertiesService.ts
index c3f8fc53dbf..334182c5f17 100644
--- a/src/vs/workbench/services/extensions/common/extensionManifestPropertiesService.ts
+++ b/src/vs/workbench/services/extensions/common/extensionManifestPropertiesService.ts
@@ -4,7 +4,8 @@
*--------------------------------------------------------------------------------------------*/
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
-import { IExtensionManifest, ExtensionKind, ExtensionIdentifier, ExtensionUntrustedWorkspaceSupportType, ExtensionVirtualWorkspaceSupportType, IExtensionIdentifier, ALL_EXTENSION_KINDS } from 'vs/platform/extensions/common/extensions';
+import { IExtensionManifest, ExtensionIdentifier, ExtensionUntrustedWorkspaceSupportType, ExtensionVirtualWorkspaceSupportType, IExtensionIdentifier, ALL_EXTENSION_KINDS } from 'vs/platform/extensions/common/extensions';
+import { ExtensionKind } from 'vs/platform/environment/common/environment';
import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry';
import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { isNonEmptyArray } from 'vs/base/common/arrays';
diff --git a/src/vs/workbench/services/extensions/common/extensionsRegistry.ts b/src/vs/workbench/services/extensions/common/extensionsRegistry.ts
index 7ade0916dd0..008efa90af4 100644
--- a/src/vs/workbench/services/extensions/common/extensionsRegistry.ts
+++ b/src/vs/workbench/services/extensions/common/extensionsRegistry.ts
@@ -11,7 +11,8 @@ import { EXTENSION_IDENTIFIER_PATTERN } from 'vs/platform/extensionManagement/co
import { Extensions, IJSONContributionRegistry } from 'vs/platform/jsonschemas/common/jsonContributionRegistry';
import { Registry } from 'vs/platform/registry/common/platform';
import { IMessage } from 'vs/workbench/services/extensions/common/extensions';
-import { ExtensionIdentifier, IExtensionDescription, EXTENSION_CATEGORIES, ExtensionKind } from 'vs/platform/extensions/common/extensions';
+import { ExtensionIdentifier, IExtensionDescription, EXTENSION_CATEGORIES } from 'vs/platform/extensions/common/extensions';
+import { ExtensionKind } from 'vs/platform/environment/common/environment';
import { allApiProposals } from 'vs/workbench/services/extensions/common/extensionsApiProposals';
import { values } from 'vs/base/common/collections';
import { productSchemaId } from 'vs/platform/product/common/productService';
diff --git a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts
index 3da31508314..582609ea7ad 100644
--- a/src/vs/workbench/services/extensions/electron-browser/extensionService.ts
+++ b/src/vs/workbench/services/extensions/electron-browser/extensionService.ts
@@ -24,7 +24,8 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IExtensionService, toExtension, ExtensionHostKind, IExtensionHost, webWorkerExtHostConfig, ExtensionRunningLocation, WebWorkerExtHostConfigValue, extensionRunningLocationToString, extensionHostKindToString } from 'vs/workbench/services/extensions/common/extensions';
import { IExtensionHostManager } from 'vs/workbench/services/extensions/common/extensionHostManager';
-import { ExtensionIdentifier, IExtension, ExtensionType, IExtensionDescription, ExtensionKind } from 'vs/platform/extensions/common/extensions';
+import { ExtensionIdentifier, IExtension, ExtensionType, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
+import { ExtensionKind } from 'vs/platform/environment/common/environment';
import { IFileService } from 'vs/platform/files/common/files';
import { PersistentConnectionEventType } from 'vs/platform/remote/common/remoteAgentConnection';
import { IProductService } from 'vs/platform/product/common/productService';
diff --git a/src/vs/workbench/services/path/common/pathService.ts b/src/vs/workbench/services/path/common/pathService.ts
index 8261fca7925..5f407090cbe 100644
--- a/src/vs/workbench/services/path/common/pathService.ts
+++ b/src/vs/workbench/services/path/common/pathService.ts
@@ -10,7 +10,7 @@ import { OperatingSystem, OS } from 'vs/base/common/platform';
import { basename } from 'vs/base/common/resources';
import { URI } from 'vs/base/common/uri';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
-import { getVirtualWorkspaceScheme } from 'vs/platform/remote/common/remoteHosts';
+import { getVirtualWorkspaceScheme } from 'vs/platform/workspace/common/virtualWorkspace';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
diff --git a/src/vs/workbench/services/remote/common/remoteExplorerService.ts b/src/vs/workbench/services/remote/common/remoteExplorerService.ts
index da201ae4735..db4f9c6cf83 100644
--- a/src/vs/workbench/services/remote/common/remoteExplorerService.ts
+++ b/src/vs/workbench/services/remote/common/remoteExplorerService.ts
@@ -8,11 +8,11 @@ import { Event, Emitter } from 'vs/base/common/event';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
-import { ALL_INTERFACES_ADDRESSES, isAllInterfaces, isLocalhost, ITunnelService, LOCALHOST_ADDRESSES, PortAttributesProvider, ProvidedOnAutoForward, ProvidedPortAttributes, RemoteTunnel, TunnelPrivacy, TunnelPrivacyId, TunnelProtocol } from 'vs/platform/remote/common/tunnel';
+import { ALL_INTERFACES_ADDRESSES, isAllInterfaces, isLocalhost, ITunnelService, LOCALHOST_ADDRESSES, PortAttributesProvider, ProvidedOnAutoForward, ProvidedPortAttributes, RemoteTunnel, TunnelPrivacyId, TunnelProtocol } from 'vs/platform/tunnel/common/tunnel';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { IEditableData } from 'vs/workbench/common/views';
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
-import { TunnelInformation, TunnelDescription, IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver';
+import { TunnelInformation, TunnelDescription, IRemoteAuthorityResolverService, TunnelPrivacy } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IAddressProvider } from 'vs/platform/remote/common/remoteAgentConnection';
import { isNumber, isObject, isString } from 'vs/base/common/types';
diff --git a/src/vs/workbench/services/remote/browser/tunnelService.ts b/src/vs/workbench/services/tunnel/browser/tunnelService.ts
index 4dcabd046bc..d433bb69371 100644
--- a/src/vs/workbench/services/remote/browser/tunnelService.ts
+++ b/src/vs/workbench/services/tunnel/browser/tunnelService.ts
@@ -7,7 +7,7 @@ import { URI } from 'vs/base/common/uri';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ILogService } from 'vs/platform/log/common/log';
import { IAddressProvider } from 'vs/platform/remote/common/remoteAgentConnection';
-import { AbstractTunnelService, ITunnelService, RemoteTunnel } from 'vs/platform/remote/common/tunnel';
+import { AbstractTunnelService, ITunnelService, RemoteTunnel } from 'vs/platform/tunnel/common/tunnel';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
export class TunnelService extends AbstractTunnelService {
diff --git a/src/vs/workbench/services/remote/electron-sandbox/tunnelService.ts b/src/vs/workbench/services/tunnel/electron-sandbox/tunnelService.ts
index 12791bcd23a..505f814d12c 100644
--- a/src/vs/workbench/services/remote/electron-sandbox/tunnelService.ts
+++ b/src/vs/workbench/services/tunnel/electron-sandbox/tunnelService.ts
@@ -7,7 +7,7 @@ import { ILogService } from 'vs/platform/log/common/log';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { URI } from 'vs/base/common/uri';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
-import { ITunnelService, AbstractTunnelService, RemoteTunnel, TunnelPrivacyId } from 'vs/platform/remote/common/tunnel';
+import { ITunnelService, AbstractTunnelService, RemoteTunnel, TunnelPrivacyId } from 'vs/platform/tunnel/common/tunnel';
import { Disposable } from 'vs/base/common/lifecycle';
import { IAddressProvider } from 'vs/platform/remote/common/remoteAgentConnection';
import { ISharedProcessTunnelService } from 'vs/platform/remote/common/sharedProcessTunnelService';
diff --git a/src/vs/workbench/services/workspaces/common/workspaceTrust.ts b/src/vs/workbench/services/workspaces/common/workspaceTrust.ts
index 6f315a7cf90..d326da2b0c5 100644
--- a/src/vs/workbench/services/workspaces/common/workspaceTrust.ts
+++ b/src/vs/workbench/services/workspaces/common/workspaceTrust.ts
@@ -12,7 +12,8 @@ import { IPath } from 'vs/platform/windows/common/windows';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IRemoteAuthorityResolverService, ResolverResult } from 'vs/platform/remote/common/remoteAuthorityResolver';
-import { getRemoteAuthority, isVirtualResource } from 'vs/platform/remote/common/remoteHosts';
+import { getRemoteAuthority } from 'vs/platform/remote/common/remoteHosts';
+import { isVirtualResource } from 'vs/platform/workspace/common/virtualWorkspace';
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { WorkspaceTrustRequestOptions, IWorkspaceTrustManagementService, IWorkspaceTrustInfo, IWorkspaceTrustUriInfo, IWorkspaceTrustRequestService, IWorkspaceTrustTransitionParticipant, WorkspaceTrustUriResponse, IWorkspaceTrustEnablementService } from 'vs/platform/workspace/common/workspaceTrust';
diff --git a/src/vs/workbench/workbench.sandbox.main.ts b/src/vs/workbench/workbench.sandbox.main.ts
index 7c3a50d21da..4b363e7b336 100644
--- a/src/vs/workbench/workbench.sandbox.main.ts
+++ b/src/vs/workbench/workbench.sandbox.main.ts
@@ -74,7 +74,7 @@ import 'vs/workbench/services/integrity/electron-sandbox/integrityService';
import 'vs/workbench/services/workingCopy/electron-sandbox/workingCopyBackupService';
import 'vs/workbench/services/checksum/electron-sandbox/checksumService';
import 'vs/platform/remote/electron-sandbox/sharedProcessTunnelService';
-import 'vs/workbench/services/remote/electron-sandbox/tunnelService';
+import 'vs/workbench/services/tunnel/electron-sandbox/tunnelService';
import 'vs/platform/diagnostics/electron-sandbox/diagnosticsService';
import 'vs/platform/profiling/electron-sandbox/profilingService';
import 'vs/platform/telemetry/electron-sandbox/customEndpointTelemetryService';
diff --git a/src/vs/workbench/workbench.web.api.ts b/src/vs/workbench/workbench.web.api.ts
index ab8bbf4f72e..bcbafa4283f 100644
--- a/src/vs/workbench/workbench.web.api.ts
+++ b/src/vs/workbench/workbench.web.api.ts
@@ -17,7 +17,7 @@ import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { IProductConfiguration } from 'vs/base/common/product';
import { mark } from 'vs/base/common/performance';
import { ICredentialsProvider } from 'vs/platform/credentials/common/credentials';
-import { TunnelProviderFeatures } from 'vs/platform/remote/common/tunnel';
+import { TunnelProviderFeatures } from 'vs/platform/tunnel/common/tunnel';
import { MenuId, MenuRegistry } from 'vs/platform/actions/common/actions';
import { DeferredPromise } from 'vs/base/common/async';
import { asArray } from 'vs/base/common/arrays';
diff --git a/src/vs/workbench/workbench.web.main.ts b/src/vs/workbench/workbench.web.main.ts
index 961f2d087ba..83d5ccd3287 100644
--- a/src/vs/workbench/workbench.web.main.ts
+++ b/src/vs/workbench/workbench.web.main.ts
@@ -57,7 +57,7 @@ import 'vs/workbench/services/path/browser/pathService';
import 'vs/workbench/services/themes/browser/browserHostColorSchemeService';
import 'vs/workbench/services/encryption/browser/encryptionService';
import 'vs/workbench/services/workingCopy/browser/workingCopyBackupService';
-import 'vs/workbench/services/remote/browser/tunnelService';
+import 'vs/workbench/services/tunnel/browser/tunnelService';
import 'vs/workbench/services/files/browser/elevatedFileService';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
diff --git a/src/vscode-dts/vscode.proposed.scmActionButton.d.ts b/src/vscode-dts/vscode.proposed.scmActionButton.d.ts
index f60dc3047c7..82b4b936abc 100644
--- a/src/vscode-dts/vscode.proposed.scmActionButton.d.ts
+++ b/src/vscode-dts/vscode.proposed.scmActionButton.d.ts
@@ -6,7 +6,12 @@
declare module 'vscode' {
// https://github.com/microsoft/vscode/issues/133935
+ export interface SourceControlActionButton {
+ command: Command;
+ description?: string;
+ }
+
export interface SourceControl {
- actionButton?: Command;
+ actionButton?: SourceControlActionButton;
}
}
diff --git a/test/automation/src/playwrightDriver.ts b/test/automation/src/playwrightDriver.ts
index 00b6c3ef3d4..fe7fd72050f 100644
--- a/test/automation/src/playwrightDriver.ts
+++ b/test/automation/src/playwrightDriver.ts
@@ -14,6 +14,7 @@ import * as kill from 'tree-kill';
import { PageFunction } from 'playwright-core/types/structs';
import { Logger, measureAndLog } from './logger';
import type { LaunchOptions } from './code';
+import * as crypto from 'crypto';
const width = 1200;
const height = 800;
@@ -224,7 +225,7 @@ async function launchServer(options: LaunchOptions) {
...process.env
};
- const args = ['--disable-telemetry', '--port', `${port++}`, '--driver', 'web', '--extensions-dir', extensionsPath, '--server-data-dir', agentFolder];
+ const args = ['--connection-token', String(crypto.randomInt(0xffffffff)), '--disable-telemetry', '--port', `${port++}`, '--driver', 'web', '--extensions-dir', extensionsPath, '--server-data-dir', agentFolder];
let serverLocation: string | undefined;
if (codeServerPath) {