labels - make getPathLabel aware of remote OS

This commit is contained in:
Benjamin Pasero
2022-04-26 18:09:01 +02:00
parent 32cd2a6dfb
commit 8a39cb9304
15 changed files with 137 additions and 110 deletions

View File

@@ -317,9 +317,8 @@ export function isRootOrDriveLetter(path: string): boolean {
return pathNormalized === posix.sep;
}
export function hasDriveLetter(path: string, continueAsWindows?: boolean): boolean {
const isWindowsPath: boolean = ((continueAsWindows !== undefined) ? continueAsWindows : isWindows);
if (isWindowsPath) {
export function hasDriveLetter(path: string, isWindowsOS: boolean = isWindows): boolean {
if (isWindowsOS) {
return isWindowsDriveLetter(path.charCodeAt(0)) && path.charCodeAt(1) === CharCode.Colon;
}

View File

@@ -5,12 +5,36 @@
import { hasDriveLetter, isRootOrDriveLetter } from 'vs/base/common/extpath';
import { Schemas } from 'vs/base/common/network';
import { normalize, posix, sep, win32 } from 'vs/base/common/path';
import { isLinux, isMacintosh, isWindows } from 'vs/base/common/platform';
import { basename, isEqual, relativePath } from 'vs/base/common/resources';
import { posix, sep, win32 } from 'vs/base/common/path';
import { isMacintosh, isWindows, OperatingSystem, OS } from 'vs/base/common/platform';
import { basename, extUri, extUriIgnorePathCase } from 'vs/base/common/resources';
import { rtrim, startsWithIgnoreCase } from 'vs/base/common/strings';
import { URI } from 'vs/base/common/uri';
export interface IPathLabelFormatting {
/**
* The OS the path label is from to produce a label
* that matches OS expectations.
*/
readonly os: OperatingSystem;
/**
* Whether to add a `~` when the path is in the
* user home directory.
*
* Note: this only applies to Linux, macOS but not
* Windows.
*/
readonly tildify?: IUserHomeProvider;
/**
* Whether to convert to a relative path if the path
* is within any of the opened workspace folders.
*/
readonly relative?: IWorkspaceFolderProvider;
}
export interface IWorkspaceFolderProvider {
getWorkspaceFolder(resource: URI): { uri: URI; name?: string } | null;
getWorkspace(): {
@@ -19,15 +43,13 @@ export interface IWorkspaceFolderProvider {
}
export interface IUserHomeProvider {
userHome?: URI;
userHome: URI;
}
/**
* @deprecated use `ILabelService` instead where contributed label
* formatters are being used. this method is only suitable as a fallback
* when formatters are unknown.
*/
export function getPathLabel(resource: URI, userHomeProvider?: IUserHomeProvider, rootProvider?: IWorkspaceFolderProvider): string {
export function getPathLabel(resource: URI, formatting: IPathLabelFormatting): string {
const { os, tildify: userHomeProvider, relative: rootProvider } = formatting;
const pathLib = os === OperatingSystem.Windows ? win32 : posix;
const extUriLib = os === OperatingSystem.Linux ? extUri : extUriIgnorePathCase;
// return early if we can resolve a relative path label from the root
if (rootProvider) {
@@ -36,19 +58,19 @@ export function getPathLabel(resource: URI, userHomeProvider?: IUserHomeProvider
const hasMultipleRoots = rootProvider.getWorkspace().folders.length > 1;
let pathLabel: string;
if (isEqual(baseResource.uri, resource)) {
if (extUriLib.isEqual(baseResource.uri, resource)) {
pathLabel = ''; // no label if paths are identical
} else {
pathLabel = relativePath(baseResource.uri, resource) ?? '';
pathLabel = extUriLib.relativePath(baseResource.uri, resource) ?? '';
// normalize
if (pathLabel) {
pathLabel = normalize(pathLabel);
pathLabel = pathLib.normalize(pathLabel);
}
}
if (hasMultipleRoots) {
const rootName = baseResource.name ? baseResource.name : basename(baseResource.uri);
const rootName = baseResource.name ? baseResource.name : extUriLib.basename(baseResource.uri);
pathLabel = pathLabel ? `${rootName}${pathLabel}` : rootName; // always show root basename if there are multiple
}
@@ -57,16 +79,14 @@ export function getPathLabel(resource: URI, userHomeProvider?: IUserHomeProvider
}
// normalize
let res = normalize(resource.fsPath);
let res = pathLib.normalize(resource.fsPath);
// Windows: normalize drive letter
if (hasDriveLetter(res)) {
res = normalizeDriveLetter(res);
}
res = normalizeDriveLetter(res, os === OperatingSystem.Windows);
// macOS/Linux: tildify
if (!isWindows && userHomeProvider?.userHome) {
res = tildify(res, userHomeProvider.userHome.fsPath);
if (os !== OperatingSystem.Windows && userHomeProvider?.userHome) {
res = tildify(res, userHomeProvider.userHome.fsPath, os);
}
return res;
@@ -93,8 +113,8 @@ export function getBaseLabel(resource: URI | string | undefined): string | undef
return base;
}
export function normalizeDriveLetter(path: string, continueAsWindows?: boolean): string {
if (hasDriveLetter(path, continueAsWindows)) {
export function normalizeDriveLetter(path: string, isWindowsOS: boolean = isWindows): string {
if (hasDriveLetter(path, isWindowsOS)) {
return path.charAt(0).toUpperCase() + path.slice(1);
}
@@ -102,8 +122,8 @@ export function normalizeDriveLetter(path: string, continueAsWindows?: boolean):
}
let normalizedUserHomeCached: { original: string; normalized: string } = Object.create(null);
export function tildify(path: string, userHome: string): string {
if (isWindows || !path || !userHome) {
export function tildify(path: string, userHome: string, os = OS): string {
if (os === OperatingSystem.Windows || !path || !userHome) {
return path; // unsupported
}
@@ -115,7 +135,7 @@ export function tildify(path: string, userHome: string): string {
}
// Linux: case sensitive, macOS: case insensitive
if (isLinux ? path.startsWith(normalizedUserHome) : startsWithIgnoreCase(path, normalizedUserHome)) {
if (os === OperatingSystem.Linux ? path.startsWith(normalizedUserHome) : startsWithIgnoreCase(path, normalizedUserHome)) {
path = `~/${path.substr(normalizedUserHome.length)}`;
}

View File

@@ -17,7 +17,7 @@ import { getPathLabel, mnemonicButtonLabel } from 'vs/base/common/labels';
import { Disposable } from 'vs/base/common/lifecycle';
import { Schemas } from 'vs/base/common/network';
import { isAbsolute, join, posix } from 'vs/base/common/path';
import { IProcessEnvironment, isLinux, isLinuxSnap, isMacintosh, isWindows } from 'vs/base/common/platform';
import { IProcessEnvironment, isLinux, isLinuxSnap, isMacintosh, isWindows, OS } from 'vs/base/common/platform';
import { assertType, withNullAsUndefined } from 'vs/base/common/types';
import { URI } from 'vs/base/common/uri';
import { generateUuid } from 'vs/base/common/uuid';
@@ -992,7 +992,7 @@ export class CodeApplication extends Disposable {
],
defaultId: 0,
cancelId: 1,
message: localize('confirmOpenMessage', "An external application wants to open '{0}' in {1}. Do you want to open this file or folder?", getPathLabel(uri, this.environmentMainService), this.productService.nameShort),
message: localize('confirmOpenMessage', "An external application wants to open '{0}' in {1}. Do you want to open this file or folder?", getPathLabel(uri, { os: OS, tildify: this.environmentMainService }), this.productService.nameShort),
detail: localize('confirmOpenDetail', "If you did not initiate this request, it may represent an attempted attack on your system. Unless you took an explicit action to initiate this request, you should press 'No'"),
noLink: true
});

View File

@@ -18,7 +18,7 @@ import { getPathLabel, mnemonicButtonLabel } from 'vs/base/common/labels';
import { Schemas } from 'vs/base/common/network';
import { basename, join, resolve } from 'vs/base/common/path';
import { mark } from 'vs/base/common/performance';
import { IProcessEnvironment, isMacintosh, isWindows } from 'vs/base/common/platform';
import { IProcessEnvironment, isMacintosh, isWindows, OS } from 'vs/base/common/platform';
import { cwd } from 'vs/base/common/process';
import { rtrim, trim } from 'vs/base/common/strings';
import { Promises as FSPromises } from 'vs/base/node/pfs';
@@ -366,7 +366,7 @@ class CodeMain {
private handleStartupDataDirError(environmentMainService: IEnvironmentMainService, title: string, error: NodeJS.ErrnoException): void {
if (error.code === 'EACCES' || error.code === 'EPERM') {
const directories = coalesce([environmentMainService.userDataPath, environmentMainService.extensionsPath, XDG_RUNTIME_DIR]).map(folder => getPathLabel(URI.file(folder), environmentMainService));
const directories = coalesce([environmentMainService.userDataPath, environmentMainService.extensionsPath, XDG_RUNTIME_DIR]).map(folder => getPathLabel(URI.file(folder), { os: OS, tildify: environmentMainService }));
this.showStartupWarningDialog(
localize('startupDataDirError', "Unable to write program user data."),

View File

@@ -17,7 +17,7 @@ import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { Schemas } from 'vs/base/common/network';
import { basename, join, normalize, posix } from 'vs/base/common/path';
import { getMarks, mark } from 'vs/base/common/performance';
import { IProcessEnvironment, isMacintosh, isWindows } from 'vs/base/common/platform';
import { IProcessEnvironment, isMacintosh, isWindows, OS } from 'vs/base/common/platform';
import { cwd } from 'vs/base/common/process';
import { extUriBiasedIgnorePathCase, isEqualAuthority, normalizePath, originalFSPath, removeTrailingPathSeparator } from 'vs/base/common/resources';
import { assertIsDefined, withNullAsUndefined } from 'vs/base/common/types';
@@ -767,7 +767,7 @@ export class WindowsMainService extends Disposable implements IWindowsMainServic
defaultId: 0,
message: uri.scheme === Schemas.file ? localize('pathNotExistTitle', "Path does not exist") : localize('uriInvalidTitle', "URI can not be opened"),
detail: uri.scheme === Schemas.file ?
localize('pathNotExistDetail', "The path '{0}' does not exist on this computer.", getPathLabel(uri, this.environmentMainService)) :
localize('pathNotExistDetail', "The path '{0}' does not exist on this computer.", getPathLabel(uri, { os: OS, tildify: this.environmentMainService })) :
localize('uriInvalidDetail', "The URI '{0}' is not valid and can not be opened.", uri.toString(true)),
noLink: true
};

View File

@@ -22,9 +22,8 @@ import { AuthenticationService } from 'vs/workbench/services/authentication/brow
import { IAuthenticationService } from 'vs/workbench/services/authentication/common/authentication';
import { IExtensionService, nullExtensionDescription as extensionDescription } from 'vs/workbench/services/extensions/common/extensions';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { TestRemoteAgentService } from 'vs/workbench/services/remote/test/common/testServices';
import { TestRPCProtocol } from 'vs/workbench/api/test/common/testRPCProtocol';
import { TestQuickInputService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestQuickInputService, TestRemoteAgentService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestActivityService, TestExtensionService, TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
import type { AuthenticationProvider, AuthenticationSession } from 'vscode';

View File

@@ -12,7 +12,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { ContextKeyService } from 'vs/platform/contextkey/browser/contextKeyService';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { TestEditorService, TestLifecycleService, TestTerminalEditorService, TestTerminalGroupService, TestTerminalInstanceService, TestTerminalProfileService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestEditorService, TestLifecycleService, TestRemoteAgentService, TestTerminalEditorService, TestTerminalGroupService, TestTerminalInstanceService, TestTerminalProfileService } from 'vs/workbench/test/browser/workbenchTestServices';
import { ITerminalEditorService, ITerminalGroupService, ITerminalInstance, ITerminalInstanceService, ITerminalService } from 'vs/workbench/contrib/terminal/browser/terminal';
import { ILifecycleService } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { IThemeService } from 'vs/platform/theme/common/themeService';
@@ -22,7 +22,6 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { TestRemoteAgentService } from 'vs/workbench/services/remote/test/common/testServices';
suite('Workbench - TerminalService', () => {
let instantiationService: TestInstantiationService;

View File

@@ -6,8 +6,7 @@
import * as assert from 'assert';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { BrowserCredentialsService } from 'vs/workbench/services/credentials/browser/credentialsService';
import { TestRemoteAgentService } from 'vs/workbench/services/remote/test/common/testServices';
import { TestEnvironmentService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestEnvironmentService, TestRemoteAgentService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestProductService } from 'vs/workbench/test/common/workbenchTestServices';
suite('CredentialsService - web', () => {

View File

@@ -21,6 +21,8 @@ import { LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IPathService } from 'vs/workbench/services/path/common/pathService';
import { isProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
import { OS } from 'vs/base/common/platform';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
const resourceLabelFormattersExtPoint = ExtensionsRegistry.registerExtensionPoint<ResourceLabelFormatter[]>({
extensionPoint: 'resourceLabelFormatters',
@@ -106,12 +108,29 @@ export class LabelService extends Disposable implements ILabelService {
private readonly _onDidChangeFormatters = this._register(new Emitter<IFormatterChangeEvent>({ leakWarningThreshold: 400 }));
readonly onDidChangeFormatters = this._onDidChangeFormatters.event;
private os = OS;
private userHome: URI | undefined = undefined;
constructor(
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IPathService private readonly pathService: IPathService
@IPathService private readonly pathService: IPathService,
@IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService
) {
super();
// Resolve OS & Paths with remote in mind
this.resolveEnvironment();
}
private async resolveEnvironment(): Promise<void> {
// OS
const env = await this.remoteAgentService.getEnvironment();
this.os = env?.os ?? OS;
// User home
this.userHome = await this.pathService.userHome();
}
findFormatting(resource: URI): ResourceLabelFormatting | undefined {
@@ -165,7 +184,11 @@ export class LabelService extends Disposable implements ILabelService {
const defaultResource = toLocalResource(resource, this.environmentService.remoteAuthority, this.pathService.defaultUriScheme);
return getPathLabel(defaultResource, { userHome: this.pathService.resolvedUserHome }, options.relative ? this.contextService : undefined);
return getPathLabel(defaultResource, {
os: this.os,
tildify: this.userHome ? { userHome: this.userHome } : undefined,
relative: options.relative ? this.contextService : undefined
});
}
let label: string | undefined;
@@ -328,9 +351,8 @@ export class LabelService extends Disposable implements ILabelService {
}
if (formatting.tildify && !forceNoTildify) {
const userHome = this.pathService.resolvedUserHome;
if (userHome) {
label = tildify(label, userHome.fsPath);
if (this.userHome) {
label = tildify(label, this.userHome.fsPath, this.os);
}
}
if (formatting.authorityPrefix && resource.authority) {

View File

@@ -5,7 +5,7 @@
import * as resources from 'vs/base/common/resources';
import * as assert from 'assert';
import { TestEnvironmentService, TestPathService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestEnvironmentService, TestPathService, TestRemoteAgentService } from 'vs/workbench/test/browser/workbenchTestServices';
import { URI } from 'vs/base/common/uri';
import { LabelService } from 'vs/workbench/services/label/common/labelService';
import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices';
@@ -17,7 +17,7 @@ suite('URI Label', () => {
let labelService: LabelService;
setup(() => {
labelService = new LabelService(TestEnvironmentService, new TestContextService(), new TestPathService());
labelService = new LabelService(TestEnvironmentService, new TestContextService(), new TestPathService(), new TestRemoteAgentService());
});
test('custom scheme', function () {
@@ -177,7 +177,9 @@ suite('multi-root workspace', () => {
new WorkspaceFolder({ uri: tests, index: 1, name: 'Tests' }),
new WorkspaceFolder({ uri: other, index: 2, name: resources.basename(other) }),
])),
new TestPathService());
new TestPathService(),
new TestRemoteAgentService()
);
});
test('labels of files in multiroot workspaces are the foldername followed by offset from the folder', () => {
@@ -260,7 +262,9 @@ suite('multi-root workspace', () => {
new Workspace('test-workspace', [
new WorkspaceFolder({ uri: rootFolder, index: 0, name: 'FSProotFolder' }),
])),
new TestPathService(undefined, rootFolder.scheme));
new TestPathService(undefined, rootFolder.scheme),
new TestRemoteAgentService()
);
const generated = labelService.getUriLabel(URI.parse('myscheme://myauthority/some/folder/test.txt'), { relative: true });
if (isWindows) {
@@ -283,7 +287,9 @@ suite('workspace at FSP root', () => {
new Workspace('test-workspace', [
new WorkspaceFolder({ uri: rootFolder, index: 0, name: 'FSProotFolder' }),
])),
new TestPathService());
new TestPathService(),
new TestRemoteAgentService()
);
labelService.registerFormatter({
scheme: 'myscheme',
formatting: {

View File

@@ -11,13 +11,14 @@ import { isWindows } from 'vs/base/common/platform';
import { LabelService } from 'vs/workbench/services/label/common/labelService';
import { TestContextService } from 'vs/workbench/test/common/workbenchTestServices';
import { TestNativePathService, TestEnvironmentService } from 'vs/workbench/test/electron-browser/workbenchTestServices';
import { TestRemoteAgentService } from 'vs/workbench/test/browser/workbenchTestServices';
suite('URI Label', () => {
let labelService: LabelService;
setup(() => {
labelService = new LabelService(TestEnvironmentService, new TestContextService(), new TestNativePathService());
labelService = new LabelService(TestEnvironmentService, new TestContextService(), new TestNativePathService(), new TestRemoteAgentService());
});
test('file scheme', function () {

View File

@@ -15,8 +15,7 @@ import { TestJSONEditingService } from 'vs/workbench/services/configuration/test
import { PreferencesService } from 'vs/workbench/services/preferences/browser/preferencesService';
import { IPreferencesService, ISettingsEditorOptions } from 'vs/workbench/services/preferences/common/preferences';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { TestRemoteAgentService } from 'vs/workbench/services/remote/test/common/testServices';
import { ITestInstantiationService, TestEditorService, workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestRemoteAgentService, ITestInstantiationService, TestEditorService, workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
suite('PreferencesService', () => {

View File

@@ -1,53 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { URI } from 'vs/base/common/uri';
import { IDiagnosticInfoOptions, IDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnostics';
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { ISocketFactory } from 'vs/platform/remote/common/remoteAgentConnection';
import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment';
import { ITelemetryData, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { IExtensionHostExitInfo, IRemoteAgentConnection, IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
export class TestRemoteAgentService implements IRemoteAgentService {
_serviceBrand: undefined;
socketFactory: ISocketFactory = {
connect() { }
};
getConnection(): IRemoteAgentConnection | null {
throw new Error('Method not implemented.');
}
getEnvironment(): Promise<IRemoteAgentEnvironment | null> {
throw new Error('Method not implemented.');
}
getRawEnvironment(): Promise<IRemoteAgentEnvironment | null> {
throw new Error('Method not implemented.');
}
getExtensionHostExitInfo(reconnectionToken: string): Promise<IExtensionHostExitInfo | null> {
throw new Error('Method not implemented.');
}
whenExtensionsReady(): Promise<void> {
throw new Error('Method not implemented.');
}
scanExtensions(skipExtensions?: ExtensionIdentifier[]): Promise<IExtensionDescription[]> {
throw new Error('Method not implemented.');
}
scanSingleExtension(extensionLocation: URI, isBuiltin: boolean): Promise<IExtensionDescription | null> {
throw new Error('Method not implemented.');
}
getDiagnosticInfo(options: IDiagnosticInfoOptions): Promise<IDiagnosticInfo | undefined> {
throw new Error('Method not implemented.');
}
updateTelemetryLevel(telemetryLevel: TelemetryLevel): Promise<void> {
throw new Error('Method not implemented.');
}
logTelemetry(eventName: string, data?: ITelemetryData): Promise<void> {
throw new Error('Method not implemented.');
}
flushTelemetry(): Promise<void> {
throw new Error('Method not implemented.');
}
}

View File

@@ -17,13 +17,12 @@ import { dirname, join } from 'vs/base/common/path';
import { Promises } from 'vs/base/node/pfs';
import { URI } from 'vs/base/common/uri';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import { TestRemoteAgentService } from 'vs/workbench/services/remote/test/common/testServices';
import { existsSync, readFileSync, unlinkSync } from 'fs';
import { IWorkingCopyHistoryEntry, IWorkingCopyHistoryEntryDescriptor, IWorkingCopyHistoryEvent } from 'vs/workbench/services/workingCopy/common/workingCopyHistory';
import { IFileService } from 'vs/platform/files/common/files';
import { UriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentityService';
import { LabelService } from 'vs/workbench/services/label/common/labelService';
import { TestLifecycleService, TestWillShutdownEvent } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestLifecycleService, TestRemoteAgentService, TestWillShutdownEvent } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
import { NativeWorkingCopyHistoryService } from 'vs/workbench/services/workingCopy/electron-sandbox/workingCopyHistoryService';
import { joinPath, dirname as resourcesDirname, basename } from 'vs/base/common/resources';
@@ -58,7 +57,7 @@ export class TestWorkingCopyHistoryService extends NativeWorkingCopyHistoryServi
const uriIdentityService = new UriIdentityService(fileService);
const labelService = new LabelService(environmentService, new TestContextService(), new TestNativePathService());
const labelService = new LabelService(environmentService, new TestContextService(), new TestNativePathService(), new TestRemoteAgentService());
const lifecycleService = new TestLifecycleService();

View File

@@ -7,7 +7,7 @@ import { FileEditorInput } from 'vs/workbench/contrib/files/browser/editors/file
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import { basename, isEqual } from 'vs/base/common/resources';
import { URI } from 'vs/base/common/uri';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { ITelemetryData, ITelemetryService, TelemetryLevel } from 'vs/platform/telemetry/common/telemetry';
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
import { EditorInput } from 'vs/workbench/common/editor/editorInput';
import { EditorInputWithOptions, IEditorIdentifier, IUntitledTextResourceEditorInput, IResourceDiffEditorInput, IEditorPane, IEditorCloseEvent, IEditorPartOptions, IRevertOptions, GroupIdentifier, EditorsOrder, IFileEditorInput, IEditorFactoryRegistry, IEditorSerializer, EditorExtensions, ISaveOptions, IMoveResult, ITextDiffEditorPane, IVisibleEditorPane, IEditorOpenContext, EditorExtensions as Extensions, EditorInputCapabilities, IUntypedEditorInput, IEditorWillMoveEvent, IEditorWillOpenEvent, IActiveEditorChangeEvent, EditorPaneSelectionChangeReason, IEditorPaneSelection } from 'vs/workbench/common/editor';
@@ -153,6 +153,12 @@ import { TextEditorPaneSelection } from 'vs/workbench/browser/parts/editor/textE
import { Selection } from 'vs/editor/common/core/selection';
import { IFolderBackupInfo, IWorkspaceBackupInfo } from 'vs/platform/backup/common/backup';
import { TestEditorWorkerService } from 'vs/editor/test/common/services/testEditorWorkerService';
import { IExtensionHostExitInfo, IRemoteAgentConnection, IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { ILanguageDetectionService } from 'vs/workbench/services/languageDetection/common/languageDetectionWorkerService';
import { IDiagnosticInfoOptions, IDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnostics';
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import { ISocketFactory } from 'vs/platform/remote/common/remoteAgentConnection';
import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment';
export function createFileEditorInput(instantiationService: IInstantiationService, resource: URI): FileEditorInput {
return instantiationService.createInstance(FileEditorInput, resource, undefined, undefined, undefined, undefined, undefined, undefined);
@@ -252,6 +258,8 @@ export function workbenchInstantiationService(
instantiationService.stub(ITextResourceConfigurationService, new TestTextResourceConfigurationService(configService));
instantiationService.stub(IUntitledTextEditorService, disposables.add(instantiationService.createInstance(UntitledTextEditorService)));
instantiationService.stub(IStorageService, disposables.add(new TestStorageService()));
instantiationService.stub(IRemoteAgentService, new TestRemoteAgentService());
instantiationService.stub(ILanguageDetectionService, new TestLanguageDetectionService());
instantiationService.stub(IPathService, overrides?.pathService ? overrides.pathService(instantiationService) : new TestPathService());
const layoutService = new TestLayoutService();
instantiationService.stub(IWorkbenchLayoutService, layoutService);
@@ -1876,3 +1884,32 @@ export class TestQuickInputService implements IQuickInputService {
back(): Promise<void> { throw new Error('not implemented.'); }
cancel(): Promise<void> { throw new Error('not implemented.'); }
}
class TestLanguageDetectionService implements ILanguageDetectionService {
declare readonly _serviceBrand: undefined;
isEnabledForLanguage(languageId: string): boolean { return false; }
async detectLanguage(resource: URI, supportedLangs?: string[] | undefined): Promise<string | undefined> { return undefined; }
}
export class TestRemoteAgentService implements IRemoteAgentService {
declare readonly _serviceBrand: undefined;
socketFactory: ISocketFactory = {
connect() { }
};
getConnection(): IRemoteAgentConnection | null { return null; }
async getEnvironment(): Promise<IRemoteAgentEnvironment | null> { return null; }
async getRawEnvironment(): Promise<IRemoteAgentEnvironment | null> { return null; }
async getExtensionHostExitInfo(reconnectionToken: string): Promise<IExtensionHostExitInfo | null> { return null; }
async whenExtensionsReady(): Promise<void> { }
scanExtensions(skipExtensions?: ExtensionIdentifier[]): Promise<IExtensionDescription[]> { throw new Error('Method not implemented.'); }
scanSingleExtension(extensionLocation: URI, isBuiltin: boolean): Promise<IExtensionDescription | null> { throw new Error('Method not implemented.'); }
async getDiagnosticInfo(options: IDiagnosticInfoOptions): Promise<IDiagnosticInfo | undefined> { return undefined; }
async updateTelemetryLevel(telemetryLevel: TelemetryLevel): Promise<void> { }
async logTelemetry(eventName: string, data?: ITelemetryData): Promise<void> { }
async flushTelemetry(): Promise<void> { }
}