Merge from vscode 10492ba146318412cbee8b76a8c630f226914734

This commit is contained in:
ADS Merger
2020-04-08 06:33:38 +00:00
parent fca2344c2e
commit 1868a7d370
339 changed files with 3795 additions and 3146 deletions

View File

@@ -4,9 +4,9 @@
*--------------------------------------------------------------------------------------------*/
import { URI } from 'vs/base/common/uri';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { INativeEnvironmentService } from 'vs/platform/environment/node/environmentService';
import { joinPath, relativePath } from 'vs/base/common/resources';
export function toBackupWorkspaceResource(backupWorkspacePath: string, environmentService: IEnvironmentService): URI {
export function toBackupWorkspaceResource(backupWorkspacePath: string, environmentService: INativeEnvironmentService): URI {
return joinPath(environmentService.userRoamingDataHome, relativePath(URI.file(environmentService.userDataPath), URI.file(backupWorkspacePath))!);
}

View File

@@ -548,22 +548,34 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
private async onWorkspaceConfigurationChanged(): Promise<void> {
if (this.workspace && this.workspace.configuration) {
const previous = { data: this._configuration.toData(), workspace: this.workspace };
const change = this._configuration.compareAndUpdateWorkspaceConfiguration(this.workspaceConfiguration.getConfiguration());
let configuredFolders = await this.toValidWorkspaceFolders(toWorkspaceFolders(this.workspaceConfiguration.getFolders(), this.workspace.configuration));
const changes = this.compareFolders(this.workspace.folders, configuredFolders);
if (changes.added.length || changes.removed.length || changes.changed.length) {
this.workspace.folders = configuredFolders;
return this.onFoldersChanged()
.then(change => {
this.triggerConfigurationChange(change, previous, ConfigurationTarget.WORKSPACE_FOLDER);
this._onDidChangeWorkspaceFolders.fire(changes);
});
} else {
this.triggerConfigurationChange(change, previous, ConfigurationTarget.WORKSPACE);
let newFolders = toWorkspaceFolders(this.workspaceConfiguration.getFolders(), this.workspace.configuration);
const { added, removed, changed } = this.compareFolders(this.workspace.folders, newFolders);
/* If changed validate new folders */
if (added.length || removed.length || changed.length) {
newFolders = await this.toValidWorkspaceFolders(newFolders);
}
/* Otherwise use existing */
else {
newFolders = this.workspace.folders;
}
await this.updateWorkspaceConfiguration(newFolders, this.workspaceConfiguration.getConfiguration());
}
}
private async updateWorkspaceConfiguration(workspaceFolders: WorkspaceFolder[], configuration: ConfigurationModel): Promise<void> {
const previous = { data: this._configuration.toData(), workspace: this.workspace };
const change = this._configuration.compareAndUpdateWorkspaceConfiguration(configuration);
const changes = this.compareFolders(this.workspace.folders, workspaceFolders);
if (changes.added.length || changes.removed.length || changes.changed.length) {
this.workspace.folders = workspaceFolders;
const change = await this.onFoldersChanged();
this.triggerConfigurationChange(change, previous, ConfigurationTarget.WORKSPACE_FOLDER);
this._onDidChangeWorkspaceFolders.fire(changes);
} else {
this.triggerConfigurationChange(change, previous, ConfigurationTarget.WORKSPACE);
}
return Promise.resolve(undefined);
}
private onWorkspaceFolderConfigurationChanged(folder: IWorkspaceFolder, key?: string): Promise<void> {
@@ -619,7 +631,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
const validWorkspaceFolders = await this.toValidWorkspaceFolders(this.workspace.folders);
const { removed } = this.compareFolders(this.workspace.folders, validWorkspaceFolders);
if (removed.length) {
return this.onWorkspaceConfigurationChanged();
await this.updateWorkspaceConfiguration(validWorkspaceFolders, this.workspaceConfiguration.getConfiguration());
}
}

View File

@@ -4,16 +4,15 @@
*--------------------------------------------------------------------------------------------*/
import * as pfs from 'vs/base/node/pfs';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { join } from 'vs/base/common/path';
import { INativeEnvironmentService } from 'vs/platform/environment/node/environmentService';
import { IConfigurationCache, ConfigurationKey } from 'vs/workbench/services/configuration/common/configuration';
import { IWorkbenchEnvironmentService } from '../../environment/common/environmentService';
export class ConfigurationCache implements IConfigurationCache {
private readonly cachedConfigurations: Map<string, CachedConfiguration> = new Map<string, CachedConfiguration>();
constructor(private readonly environmentService: IWorkbenchEnvironmentService) {
constructor(private readonly environmentService: INativeEnvironmentService) {
}
read(key: ConfigurationKey): Promise<string> {
@@ -48,7 +47,7 @@ class CachedConfiguration {
constructor(
{ type, key }: ConfigurationKey,
environmentService: IEnvironmentService
environmentService: INativeEnvironmentService
) {
this.cachedConfigurationFolderPath = join(environmentService.userDataPath, 'CachedConfigurations', type, key);
this.cachedConfigurationFilePath = join(this.cachedConfigurationFolderPath, type === 'workspaces' ? 'workspace.json' : 'configuration.json');

View File

@@ -49,7 +49,6 @@ class TestEnvironmentService extends NativeWorkbenchEnvironmentService {
}
get appSettingsHome() { return this._appSettingsHome; }
}
suite('ConfigurationEditingService', () => {
@@ -107,7 +106,7 @@ suite('ConfigurationEditingService', () => {
instantiationService = <TestInstantiationService>workbenchInstantiationService();
const environmentService = new TestEnvironmentService(URI.file(workspaceDir));
instantiationService.stub(IEnvironmentService, environmentService);
const remoteAgentService = instantiationService.createInstance(RemoteAgentService, {});
const remoteAgentService = instantiationService.createInstance(RemoteAgentService);
const fileService = new FileService(new NullLogService());
const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService());
fileService.registerProvider(Schemas.file, diskFileSystemProvider);

View File

@@ -111,7 +111,7 @@ suite.skip('WorkspaceContextService - Folder', () => { // {{SQL CARBON EDIT}} sk
const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService());
fileService.registerProvider(Schemas.file, diskFileSystemProvider);
fileService.registerProvider(Schemas.userData, new FileUserDataProvider(environmentService.appSettingsHome, environmentService.backupHome, new DiskFileSystemProvider(new NullLogService()), environmentService));
workspaceContextService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, new RemoteAgentService(TestWindowConfiguration, environmentService, new RemoteAuthorityResolverService(), new SignService(undefined), new NullLogService()));
workspaceContextService = new WorkspaceService({ configurationCache: new ConfigurationCache(environmentService) }, environmentService, fileService, new RemoteAgentService(environmentService, new RemoteAuthorityResolverService(), new SignService(undefined), new NullLogService()));
return (<WorkspaceService>workspaceContextService).initialize(convertToWorkspacePayload(URI.file(folderDir)));
});
});
@@ -171,7 +171,7 @@ suite.skip('WorkspaceContextService - Workspace', () => { // {{SQL CARBON EDIT}}
instantiationService = <TestInstantiationService>workbenchInstantiationService();
const environmentService = new TestEnvironmentService(URI.file(parentDir));
const remoteAgentService = instantiationService.createInstance(RemoteAgentService, {});
const remoteAgentService = instantiationService.createInstance(RemoteAgentService);
instantiationService.stub(IRemoteAgentService, remoteAgentService);
const fileService = new FileService(new NullLogService());
const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService());
@@ -231,7 +231,7 @@ suite.skip('WorkspaceContextService - Workspace Editing', () => { // {{SQL CARBO
instantiationService = <TestInstantiationService>workbenchInstantiationService();
const environmentService = new TestEnvironmentService(URI.file(parentDir));
const remoteAgentService = instantiationService.createInstance(RemoteAgentService, {});
const remoteAgentService = instantiationService.createInstance(RemoteAgentService);
instantiationService.stub(IRemoteAgentService, remoteAgentService);
const fileService = new FileService(new NullLogService());
const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService());
@@ -492,7 +492,7 @@ suite.skip('WorkspaceService - Initialization', () => { // {{SQL CARBON EDIT}} s
const instantiationService = <TestInstantiationService>workbenchInstantiationService();
const environmentService = new TestEnvironmentService(URI.file(parentDir));
const remoteAgentService = instantiationService.createInstance(RemoteAgentService, {});
const remoteAgentService = instantiationService.createInstance(RemoteAgentService);
instantiationService.stub(IRemoteAgentService, remoteAgentService);
const fileService = new FileService(new NullLogService());
const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService());
@@ -769,7 +769,7 @@ suite.skip('WorkspaceConfigurationService - Folder', () => { // {{SQL CARBON EDI
const instantiationService = <TestInstantiationService>workbenchInstantiationService();
const environmentService = new TestEnvironmentService(URI.file(parentDir));
const remoteAgentService = instantiationService.createInstance(RemoteAgentService, {});
const remoteAgentService = instantiationService.createInstance(RemoteAgentService);
instantiationService.stub(IRemoteAgentService, remoteAgentService);
fileService = new FileService(new NullLogService());
const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService());
@@ -1194,7 +1194,7 @@ suite.skip('WorkspaceConfigurationService-Multiroot', () => { // {{SQL CARBON ED
const instantiationService = <TestInstantiationService>workbenchInstantiationService();
const environmentService = new TestEnvironmentService(URI.file(parentDir));
const remoteAgentService = instantiationService.createInstance(RemoteAgentService, {});
const remoteAgentService = instantiationService.createInstance(RemoteAgentService);
instantiationService.stub(IRemoteAgentService, remoteAgentService);
const fileService = new FileService(new NullLogService());
const diskFileSystemProvider = new DiskFileSystemProvider(new NullLogService());

View File

@@ -28,9 +28,9 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR
static readonly INPUT_OR_COMMAND_VARIABLES_PATTERN = /\${((input|command):(.*?))}/g;
constructor(
context: { getExecPath: () => string | undefined },
envVariables: IProcessEnvironment,
editorService: IEditorService,
environmentService: IWorkbenchEnvironmentService,
private readonly configurationService: IConfigurationService,
private readonly commandService: ICommandService,
private readonly workspaceContextService: IWorkspaceContextService,
@@ -48,7 +48,7 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR
return configurationService.getValue<string>(suffix, folderUri ? { resource: folderUri } : {});
},
getExecPath: (): string | undefined => {
return environmentService['execPath'];
return context.getExecPath();
},
getFilePath: (): string | undefined => {
let activeEditor = editorService.activeEditor;
@@ -349,7 +349,7 @@ export class ConfigurationResolverService extends BaseConfigurationResolverServi
@IWorkspaceContextService workspaceContextService: IWorkspaceContextService,
@IQuickInputService quickInputService: IQuickInputService
) {
super(Object.create(null), editorService, environmentService, configurationService, commandService, workspaceContextService, quickInputService);
super({ getExecPath: () => undefined }, Object.create(null), editorService, configurationService, commandService, workspaceContextService, quickInputService);
}
}

View File

@@ -13,18 +13,23 @@ import { IConfigurationResolverService } from 'vs/workbench/services/configurati
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IProcessEnvironment } from 'vs/base/common/platform';
import { BaseConfigurationResolverService } from 'vs/workbench/services/configurationResolver/browser/configurationResolverService';
import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-browser/environmentService';
export class ConfigurationResolverService extends BaseConfigurationResolverService {
constructor(
@IEditorService editorService: IEditorService,
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,
@IWorkbenchEnvironmentService environmentService: INativeWorkbenchEnvironmentService,
@IConfigurationService configurationService: IConfigurationService,
@ICommandService commandService: ICommandService,
@IWorkspaceContextService workspaceContextService: IWorkspaceContextService,
@IQuickInputService quickInputService: IQuickInputService
) {
super(process.env as IProcessEnvironment, editorService, environmentService, configurationService, commandService, workspaceContextService, quickInputService);
super({
getExecPath: (): string | undefined => {
return environmentService.execPath;
}
}, process.env as IProcessEnvironment, editorService, configurationService, commandService, workspaceContextService, quickInputService);
}
}

View File

@@ -62,7 +62,7 @@ suite('Configuration Resolver Service', () => {
index: 0,
toResource: (path: string) => uri.file(path)
};
configurationResolverService = new TestConfigurationResolverService(environmentService.userEnv, editorService, environmentService, new MockInputsConfigurationService(), mockCommandService, new TestContextService(), quickInputService);
configurationResolverService = new TestConfigurationResolverService({ getExecPath: () => undefined }, environmentService.userEnv, editorService, new MockInputsConfigurationService(), mockCommandService, new TestContextService(), quickInputService);
});
teardown(() => {
@@ -141,7 +141,7 @@ suite('Configuration Resolver Service', () => {
}
});
let service = new TestConfigurationResolverService(environmentService.userEnv, new TestEditorServiceWithActiveEditor(), environmentService, configurationService, mockCommandService, new TestContextService(), quickInputService);
let service = new TestConfigurationResolverService({ getExecPath: () => undefined }, environmentService.userEnv, new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService);
assert.strictEqual(service.resolve(workspace, 'abc ${config:editor.fontFamily} xyz'), 'abc foo xyz');
});
@@ -158,7 +158,7 @@ suite('Configuration Resolver Service', () => {
}
});
let service = new TestConfigurationResolverService(environmentService.userEnv, new TestEditorServiceWithActiveEditor(), environmentService, configurationService, mockCommandService, new TestContextService(), quickInputService);
let service = new TestConfigurationResolverService({ getExecPath: () => undefined }, environmentService.userEnv, new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService);
assert.strictEqual(service.resolve(workspace, 'abc ${config:editor.fontFamily} ${config:terminal.integrated.fontFamily} xyz'), 'abc foo bar xyz');
});
@@ -175,7 +175,7 @@ suite('Configuration Resolver Service', () => {
}
});
let service = new TestConfigurationResolverService(environmentService.userEnv, new TestEditorServiceWithActiveEditor(), environmentService, configurationService, mockCommandService, new TestContextService(), quickInputService);
let service = new TestConfigurationResolverService({ getExecPath: () => undefined }, environmentService.userEnv, new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService);
if (platform.isWindows) {
assert.strictEqual(service.resolve(workspace, 'abc ${config:editor.fontFamily} ${workspaceFolder} ${env:key1} xyz'), 'abc foo \\VSCode\\workspaceLocation Value for key1 xyz');
} else {
@@ -196,7 +196,7 @@ suite('Configuration Resolver Service', () => {
}
});
let service = new TestConfigurationResolverService(environmentService.userEnv, new TestEditorServiceWithActiveEditor(), environmentService, configurationService, mockCommandService, new TestContextService(), quickInputService);
let service = new TestConfigurationResolverService({ getExecPath: () => undefined }, environmentService.userEnv, new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService);
if (platform.isWindows) {
assert.strictEqual(service.resolve(workspace, '${config:editor.fontFamily} ${config:terminal.integrated.fontFamily} ${workspaceFolder} - ${workspaceFolder} ${env:key1} - ${env:key2}'), 'foo bar \\VSCode\\workspaceLocation - \\VSCode\\workspaceLocation Value for key1 - Value for key2');
} else {
@@ -230,7 +230,7 @@ suite('Configuration Resolver Service', () => {
}
});
let service = new TestConfigurationResolverService(environmentService.userEnv, new TestEditorServiceWithActiveEditor(), environmentService, configurationService, mockCommandService, new TestContextService(), quickInputService);
let service = new TestConfigurationResolverService({ getExecPath: () => undefined }, environmentService.userEnv, new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService);
assert.strictEqual(service.resolve(workspace, 'abc ${config:editor.fontFamily} ${config:editor.lineNumbers} ${config:editor.insertSpaces} xyz'), 'abc foo 123 false xyz');
});
@@ -240,7 +240,7 @@ suite('Configuration Resolver Service', () => {
editor: {}
});
let service = new TestConfigurationResolverService(environmentService.userEnv, new TestEditorServiceWithActiveEditor(), environmentService, configurationService, mockCommandService, new TestContextService(), quickInputService);
let service = new TestConfigurationResolverService({ getExecPath: () => undefined }, environmentService.userEnv, new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService);
assert.strictEqual(service.resolve(workspace, 'abc ${unknownVariable} xyz'), 'abc ${unknownVariable} xyz');
assert.strictEqual(service.resolve(workspace, 'abc ${env:unknownVariable} xyz'), 'abc xyz');
});
@@ -253,7 +253,7 @@ suite('Configuration Resolver Service', () => {
}
});
let service = new TestConfigurationResolverService(environmentService.userEnv, new TestEditorServiceWithActiveEditor(), environmentService, configurationService, mockCommandService, new TestContextService(), quickInputService);
let service = new TestConfigurationResolverService({ getExecPath: () => undefined }, environmentService.userEnv, new TestEditorServiceWithActiveEditor(), configurationService, mockCommandService, new TestContextService(), quickInputService);
assert.throws(() => service.resolve(workspace, 'abc ${env} xyz'));
assert.throws(() => service.resolve(workspace, 'abc ${env:} xyz'));

View File

@@ -169,10 +169,10 @@ class DecorationStyles {
class FileDecorationChangeEvent implements IResourceDecorationChangeEvent {
private readonly _data = TernarySearchTree.forPaths<boolean>();
private readonly _data = TernarySearchTree.forUris<boolean>();
affectsResource(uri: URI): boolean {
return this._data.get(uri.toString()) || this._data.findSuperstr(uri.toString()) !== undefined;
return this._data.get(uri) || this._data.findSuperstr(uri) !== undefined;
}
static debouncer(last: FileDecorationChangeEvent | undefined, current: URI | URI[]) {
@@ -182,11 +182,11 @@ class FileDecorationChangeEvent implements IResourceDecorationChangeEvent {
if (Array.isArray(current)) {
// many
for (const uri of current) {
last._data.set(uri.toString(), true);
last._data.set(uri, true);
}
} else {
// one
last._data.set(current.toString(), true);
last._data.set(current, true);
}
return last;
@@ -202,7 +202,7 @@ class DecorationDataRequest {
class DecorationProviderWrapper {
readonly data = TernarySearchTree.forPaths<DecorationDataRequest | IDecorationData | null>();
readonly data = TernarySearchTree.forUris<DecorationDataRequest | IDecorationData | null>();
private readonly _dispoable: IDisposable;
constructor(
@@ -234,12 +234,12 @@ class DecorationProviderWrapper {
}
knowsAbout(uri: URI): boolean {
return Boolean(this.data.get(uri.toString())) || Boolean(this.data.findSuperstr(uri.toString()));
return Boolean(this.data.get(uri)) || Boolean(this.data.findSuperstr(uri));
}
getOrRetrieve(uri: URI, includeChildren: boolean, callback: (data: IDecorationData, isChild: boolean) => void): void {
const key = uri.toString();
let item = this.data.get(key);
let item = this.data.get(uri);
if (item === undefined) {
// unknown -> trigger request
@@ -253,7 +253,7 @@ class DecorationProviderWrapper {
if (includeChildren) {
// (resolved) children
const iter = this.data.findSuperstr(key);
const iter = this.data.findSuperstr(uri);
if (iter) {
for (let item = iter.next(); !item.done; item = iter.next()) {
if (item.value && !(item.value instanceof DecorationDataRequest)) {
@@ -267,10 +267,10 @@ class DecorationProviderWrapper {
private _fetchData(uri: URI): IDecorationData | null {
// check for pending request and cancel it
const pendingRequest = this.data.get(uri.toString());
const pendingRequest = this.data.get(uri);
if (pendingRequest instanceof DecorationDataRequest) {
pendingRequest.source.cancel();
this.data.delete(uri.toString());
this.data.delete(uri);
}
const source = new CancellationTokenSource();
@@ -282,23 +282,23 @@ class DecorationProviderWrapper {
} else {
// async -> we have a result soon
const request = new DecorationDataRequest(source, Promise.resolve(dataOrThenable).then(data => {
if (this.data.get(uri.toString()) === request) {
if (this.data.get(uri) === request) {
this._keepItem(uri, data);
}
}).catch(err => {
if (!isPromiseCanceledError(err) && this.data.get(uri.toString()) === request) {
this.data.delete(uri.toString());
if (!isPromiseCanceledError(err) && this.data.get(uri) === request) {
this.data.delete(uri);
}
}));
this.data.set(uri.toString(), request);
this.data.set(uri, request);
return null;
}
}
private _keepItem(uri: URI, data: IDecorationData | undefined): IDecorationData | null {
const deco = data ? data : null;
const old = this.data.set(uri.toString(), deco);
const old = this.data.set(uri, deco);
if (deco || old) {
// only fire event when something changed
this._uriEmitter.fire(uri);

View File

@@ -235,7 +235,7 @@ export class SimpleFileDialog {
if (this.scheme !== Schemas.file) {
return this.remotePathService.userHome;
}
return URI.from({ scheme: this.scheme, path: this.environmentService.userHome });
return this.environmentService.userHome!;
}
private async pickResource(isSave: boolean = false): Promise<URI | undefined> {

View File

@@ -30,7 +30,6 @@ import { EditorsObserver } from 'vs/workbench/browser/parts/editor/editorsObserv
import { IEditorViewState } from 'vs/editor/common/editorCommon';
import { IUntitledTextEditorModel } from 'vs/workbench/services/untitled/common/untitledTextEditorModel';
import { UntitledTextEditorInput } from 'vs/workbench/services/untitled/common/untitledTextEditorInput';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { timeout } from 'vs/base/common/async';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { indexOfPath } from 'vs/base/common/extpath';
@@ -68,7 +67,6 @@ export class EditorService extends Disposable implements EditorServiceImpl {
@ILabelService private readonly labelService: ILabelService,
@IFileService private readonly fileService: IFileService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService
) {
super();
@@ -348,8 +346,6 @@ export class EditorService extends Disposable implements EditorServiceImpl {
if (!exists && !editor.isDisposed()) {
editor.dispose();
} else if (this.environmentService.verbose) {
console.warn(`File exists even though we received a delete event: ${resource.toString()}`);
}
}
})();

View File

@@ -17,6 +17,7 @@ import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { EditorsObserver } from 'vs/workbench/browser/parts/editor/editorsObserver';
import { timeout } from 'vs/base/common/async';
import { TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
import { isWeb } from 'vs/base/common/platform';
const TEST_EDITOR_ID = 'MyTestEditorForEditorsObserver';
const TEST_EDITOR_INPUT_ID = 'testEditorInputForEditorsObserver';
@@ -204,7 +205,10 @@ suite.skip('EditorsObserver', function () { //{{SQL CARBON EDIT}} disable failin
part.dispose();
});
test('copy group', async () => {
test('copy group', async function () {
if (isWeb) {
this.skip();
}
const [part, observer] = await createEditorObserver();
const input1 = new TestFileEditorInput(URI.parse('foo://bar1'), TEST_SERIALIZABLE_EDITOR_INPUT_ID);

View File

@@ -8,18 +8,19 @@ import { joinPath } from 'vs/base/common/resources';
import { URI } from 'vs/base/common/uri';
import { generateUuid } from 'vs/base/common/uuid';
import { BACKUPS, 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 { IPath } from 'vs/platform/windows/common/windows';
import { IWorkbenchEnvironmentService, IEnvironmentConfiguration } from 'vs/workbench/services/environment/common/environmentService';
import { IWorkbenchConstructionOptions } from 'vs/workbench/workbench.web.api';
import product from 'vs/platform/product/common/product';
import { memoize } from 'vs/base/common/decorators';
import { onUnexpectedError } from 'vs/base/common/errors';
export class BrowserWindowConfiguration implements IWindowConfiguration {
export class BrowserEnvironmentConfiguration implements IEnvironmentConfiguration {
constructor(
private readonly options: IBrowserWorkbenchEnvironmentConstructionOptions,
private readonly payload: Map<string, string> | undefined,
private readonly environment: IWorkbenchEnvironmentService
private readonly backupHome: URI
) { }
@memoize
@@ -29,10 +30,7 @@ export class BrowserWindowConfiguration implements IWindowConfiguration {
get remoteAuthority(): string | undefined { return this.options.remoteAuthority; }
@memoize
get connectionToken(): string | undefined { return this.options.connectionToken || this.getCookieValue('vscode-tkn'); }
@memoize
get backupWorkspaceResource(): URI { return joinPath(this.environment.backupHome, this.options.workspaceId); }
get backupWorkspaceResource(): URI { return joinPath(this.backupHome, this.options.workspaceId); }
@memoize
get filesToOpenOrCreate(): IPath[] | undefined {
@@ -46,15 +44,24 @@ export class BrowserWindowConfiguration implements IWindowConfiguration {
return undefined;
}
// Currently unsupported in web but should look into support
get filesToDiff(): IPath[] | undefined { return undefined; }
highContrast = false;
_ = [];
@memoize
get filesToDiff(): IPath[] | undefined {
if (this.payload) {
const fileToDiffDetail = this.payload.get('diffFileDetail');
const fileToDiffMaster = this.payload.get('diffFileMaster');
if (fileToDiffDetail && fileToDiffMaster) {
return [
{ fileUri: URI.parse(fileToDiffDetail) },
{ fileUri: URI.parse(fileToDiffMaster) }
];
}
}
private getCookieValue(name: string): string | undefined {
const m = document.cookie.match('(^|[^;]+)\\s*' + name + '\\s*=\\s*([^;]+)'); // See https://stackoverflow.com/a/25490531
return undefined;
}
return m ? m.pop() : undefined;
get highContrast() {
return false; // could investigate to detect high contrast theme automatically
}
}
@@ -75,10 +82,10 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment
_serviceBrand: undefined;
private _configuration: IWindowConfiguration | undefined = undefined;
get configuration(): IWindowConfiguration {
private _configuration: IEnvironmentConfiguration | undefined = undefined;
get configuration(): IEnvironmentConfiguration {
if (!this._configuration) {
this._configuration = new BrowserWindowConfiguration(this.options, this.payload, this);
this._configuration = new BrowserEnvironmentConfiguration(this.options, this.payload, this.backupHome);
}
return this._configuration;
@@ -90,6 +97,8 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment
@memoize
get logsPath(): string { return this.options.logsPath.path; }
get logLevel(): string | undefined { return this.payload?.get('logLevel'); }
@memoize
get logFile(): URI { return joinPath(this.options.logsPath, 'window.log'); }
@@ -111,6 +120,8 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment
@memoize
get userDataSyncLogResource(): URI { return joinPath(this.options.logsPath, 'userDataSync.log'); }
get sync(): 'on' | 'off' { return 'on'; }
@memoize
get keybindingsResource(): URI { return joinPath(this.userRoamingDataHome, 'keybindings.json'); }
@@ -123,6 +134,9 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment
@memoize
get untitledWorkspacesHome(): URI { return joinPath(this.userRoamingDataHome, 'Workspaces'); }
@memoize
get serviceMachineIdResource(): URI { return joinPath(this.userRoamingDataHome, 'machineid'); }
private _extensionHostDebugEnvironment: IExtensionHostDebugEnvironment | undefined = undefined;
get debugExtensionHost(): IExtensionHostDebugParams {
if (!this._extensionHostDebugEnvironment) {
@@ -164,9 +178,11 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment
return this._extensionHostDebugEnvironment.extensionEnabledProposedApi;
}
get disableExtensions() { return this.payload?.get('disableExtensions') === 'true'; }
@memoize
get webviewExternalEndpoint(): string {
// TODO: get fallback from product.json
// TODO@matt: get fallback from product.json
return (this.options.webviewEndpoint || 'https://{{uuid}}.vscode-webview-test.com/{{commit}}').replace('{{commit}}', product.commit || '0d728c31ebdf03869d2687d9be0b017667c9ff37');
}
@@ -180,19 +196,20 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment
return this.webviewExternalEndpoint.replace('{{uuid}}', '*');
}
// Currently unsupported in web but should look into support
get disableExtensions() { return false; }
get extensionsPath(): string | undefined { return undefined; }
get verbose(): boolean { return false; }
get disableUpdates(): boolean { return false; }
get logExtensionHostCommunication(): boolean { return false; }
galleryMachineIdResource?: URI;
get disableTelemetry(): boolean { return false; }
get verbose(): boolean { return this.payload?.get('verbose') === 'true'; }
get logExtensionHostCommunication(): boolean { return this.payload?.get('logExtensionHostCommunication') === 'true'; }
private payload: Map<string, string> | undefined;
constructor(readonly options: IBrowserWorkbenchEnvironmentConstructionOptions) {
if (options.workspaceProvider && Array.isArray(options.workspaceProvider.payload)) {
this.payload = new Map(options.workspaceProvider.payload);
try {
this.payload = new Map(options.workspaceProvider.payload);
} catch (error) {
onUnexpectedError(error); // possible invalid payload for map
}
}
}
@@ -233,35 +250,4 @@ export class BrowserWorkbenchEnvironmentService implements IWorkbenchEnvironment
return extensionHostDebugEnvironment;
}
//#region TODO MOVE TO NODE LAYER
args = { _: [] };
mainIPCHandle!: string;
sharedIPCHandle!: string;
nodeCachedDataDir?: string;
driverHandle?: string;
driverVerbose!: boolean;
installSourcePath!: string;
builtinExtensionsPath!: string;
globalStorageHome!: string;
workspaceStorageHome!: string;
backupWorkspacesPath!: string;
machineSettingsResource!: URI;
userHome!: string;
userDataPath!: string;
appRoot!: string;
appSettingsHome!: URI;
execPath!: string;
//#endregion
}

View File

@@ -11,11 +11,15 @@ import { URI } from 'vs/base/common/uri';
export const IWorkbenchEnvironmentService = createDecorator<IWorkbenchEnvironmentService>('environmentService');
export interface IEnvironmentConfiguration extends IWindowConfiguration {
backupWorkspaceResource?: URI;
}
export interface IWorkbenchEnvironmentService extends IEnvironmentService {
_serviceBrand: undefined;
readonly configuration: IWindowConfiguration;
readonly configuration: IEnvironmentConfiguration;
readonly options?: IWorkbenchConstructionOptions;

View File

@@ -3,8 +3,8 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { EnvironmentService, INativeEnvironmentService } from 'vs/platform/environment/node/environmentService';
import { IWorkbenchEnvironmentService, IEnvironmentConfiguration } from 'vs/workbench/services/environment/common/environmentService';
import { memoize } from 'vs/base/common/decorators';
import { URI } from 'vs/base/common/uri';
import { Schemas } from 'vs/base/common/network';
@@ -13,9 +13,9 @@ import { join } from 'vs/base/common/path';
import product from 'vs/platform/product/common/product';
import { INativeWindowConfiguration } from 'vs/platform/windows/node/window';
export interface INativeWorkbenchEnvironmentService extends IWorkbenchEnvironmentService {
export interface INativeWorkbenchEnvironmentService extends IWorkbenchEnvironmentService, INativeEnvironmentService {
readonly configuration: INativeWindowConfiguration;
readonly configuration: INativeEnvironmentConfiguration;
readonly disableCrashReporter: boolean;
@@ -23,8 +23,12 @@ export interface INativeWorkbenchEnvironmentService extends IWorkbenchEnvironmen
readonly log?: string;
readonly extHostLogsPath: URI;
readonly userHome: URI;
}
export interface INativeEnvironmentConfiguration extends IEnvironmentConfiguration, INativeWindowConfiguration { }
export class NativeWorkbenchEnvironmentService extends EnvironmentService implements INativeWorkbenchEnvironmentService {
_serviceBrand: undefined;
@@ -52,7 +56,7 @@ export class NativeWorkbenchEnvironmentService extends EnvironmentService implem
get extHostLogsPath(): URI { return URI.file(join(this.logsPath, `exthost${this.configuration.windowId}`)); }
constructor(
readonly configuration: INativeWindowConfiguration,
readonly configuration: INativeEnvironmentConfiguration,
execPath: string
) {
super(configuration, execPath);

View File

@@ -94,9 +94,9 @@ export interface IExtensionRecommendation {
sources: ExtensionRecommendationSource[];
}
export const IExtensionTipsService = createDecorator<IExtensionTipsService>('extensionTipsService');
export const IExtensionRecommendationsService = createDecorator<IExtensionRecommendationsService>('extensionRecommendationsService');
export interface IExtensionTipsService {
export interface IExtensionRecommendationsService {
_serviceBrand: undefined;
getAllRecommendationsWithReason(): { [id: string]: { reasonId: ExtensionRecommendationReason, reasonText: string }; };
getFileBasedRecommendations(): IExtensionRecommendation[];

View File

@@ -0,0 +1,29 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IExtensionTipsService, IExecutableBasedExtensionTip, IWorkspaceTips } from 'vs/platform/extensionManagement/common/extensionManagement';
class WebExtensionTipsService implements IExtensionTipsService {
_serviceBrand: any;
constructor() { }
async getImportantExecutableBasedTips(): Promise<IExecutableBasedExtensionTip[]> {
return [];
}
async getOtherExecutableBasedTips(): Promise<IExecutableBasedExtensionTip[]> {
return [];
}
async getAllWorkspacesTips(): Promise<IWorkspaceTips[]> {
return [];
}
}
registerSingleton(IExtensionTipsService, WebExtensionTipsService);

View File

@@ -0,0 +1,37 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService';
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
import { IExtensionTipsService, IExecutableBasedExtensionTip, IWorkspaceTips } from 'vs/platform/extensionManagement/common/extensionManagement';
class NativeExtensionTipsService implements IExtensionTipsService {
_serviceBrand: any;
private readonly channel: IChannel;
constructor(
@ISharedProcessService sharedProcessService: ISharedProcessService
) {
this.channel = sharedProcessService.getChannel('extensionTipsService');
}
getImportantExecutableBasedTips(): Promise<IExecutableBasedExtensionTip[]> {
return this.channel.call<IExecutableBasedExtensionTip[]>('getImportantExecutableBasedTips');
}
getOtherExecutableBasedTips(): Promise<IExecutableBasedExtensionTip[]> {
return this.channel.call<IExecutableBasedExtensionTip[]>('getOtherExecutableBasedTips');
}
getAllWorkspacesTips(): Promise<IWorkspaceTips[]> {
return this.channel.call<IWorkspaceTips[]>('getAllWorkspacesTips');
}
}
registerSingleton(IExtensionTipsService, NativeExtensionTipsService);

View File

@@ -136,8 +136,6 @@ export class WebWorkerExtensionHostStarter implements IExtensionHostStarter {
parentPid: -1,
environment: {
isExtensionDevelopmentDebug: false,
appRoot: this._environmentService.appRoot ? URI.file(this._environmentService.appRoot) : undefined,
appSettingsHome: this._environmentService.appSettingsHome ? this._environmentService.appSettingsHome : undefined,
appName: this._productService.nameLong,
appUriScheme: this._productService.urlProtocol,
appLanguage: platform.language,

View File

@@ -14,7 +14,8 @@ import * as platform from 'vs/base/common/platform';
import { originalFSPath } from 'vs/base/common/resources';
import { URI } from 'vs/base/common/uri';
import * as pfs from 'vs/base/node/pfs';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-browser/environmentService';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IWorkbenchExtensionEnablementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
import { BUILTIN_MANIFEST_CACHE_FILE, MANIFEST_CACHE_FOLDER, USER_MANIFEST_CACHE_FILE, ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
import product from 'vs/platform/product/common/product';
@@ -22,8 +23,6 @@ import { INotificationService, Severity } from 'vs/platform/notification/common/
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { ExtensionScanner, ExtensionScannerInput, IExtensionReference, IExtensionResolver, IRelaxedExtensionDescription } from 'vs/workbench/services/extensions/node/extensionPoints';
import { Translations, ILog } from 'vs/workbench/services/extensions/common/extensionPoints';
import { IProductService } from 'vs/platform/product/common/productService';
import { parseBuiltInExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
interface IExtensionCacheData {
input: ExtensionScannerInput;
@@ -55,10 +54,9 @@ export class CachedExtensionScanner {
constructor(
@INotificationService private readonly _notificationService: INotificationService,
@IEnvironmentService private readonly _environmentService: IEnvironmentService,
@IWorkbenchEnvironmentService private readonly _environmentService: INativeWorkbenchEnvironmentService,
@IWorkbenchExtensionEnablementService private readonly _extensionEnablementService: IWorkbenchExtensionEnablementService,
@IHostService private readonly _hostService: IHostService,
@IProductService private readonly _productService: IProductService,
) {
this.scannedExtensions = new Promise<IExtensionDescription[]>((resolve, reject) => {
this._scannedExtensionsResolve = resolve;
@@ -81,7 +79,7 @@ export class CachedExtensionScanner {
public async startScanningExtensions(log: ILog): Promise<void> {
try {
const translations = await this.translationConfig;
const { system, user, development } = await CachedExtensionScanner._scanInstalledExtensions(this._hostService, this._notificationService, this._environmentService, this._extensionEnablementService, this._productService, log, translations);
const { system, user, development } = await CachedExtensionScanner._scanInstalledExtensions(this._hostService, this._notificationService, this._environmentService, this._extensionEnablementService, log, translations);
let result = new Map<string, IExtensionDescription>();
system.forEach((systemExtension) => {
@@ -114,7 +112,7 @@ export class CachedExtensionScanner {
}
}
private static async _validateExtensionsCache(hostService: IHostService, notificationService: INotificationService, environmentService: IEnvironmentService, cacheKey: string, input: ExtensionScannerInput): Promise<void> {
private static async _validateExtensionsCache(hostService: IHostService, notificationService: INotificationService, environmentService: INativeWorkbenchEnvironmentService, cacheKey: string, input: ExtensionScannerInput): Promise<void> {
const cacheFolder = path.join(environmentService.userDataPath, MANIFEST_CACHE_FOLDER);
const cacheFile = path.join(cacheFolder, cacheKey);
@@ -149,7 +147,7 @@ export class CachedExtensionScanner {
);
}
private static async _readExtensionCache(environmentService: IEnvironmentService, cacheKey: string): Promise<IExtensionCacheData | null> {
private static async _readExtensionCache(environmentService: INativeWorkbenchEnvironmentService, cacheKey: string): Promise<IExtensionCacheData | null> {
const cacheFolder = path.join(environmentService.userDataPath, MANIFEST_CACHE_FOLDER);
const cacheFile = path.join(cacheFolder, cacheKey);
@@ -163,7 +161,7 @@ export class CachedExtensionScanner {
return null;
}
private static async _writeExtensionCache(environmentService: IEnvironmentService, cacheKey: string, cacheContents: IExtensionCacheData): Promise<void> {
private static async _writeExtensionCache(environmentService: INativeWorkbenchEnvironmentService, cacheKey: string, cacheContents: IExtensionCacheData): Promise<void> {
const cacheFolder = path.join(environmentService.userDataPath, MANIFEST_CACHE_FOLDER);
const cacheFile = path.join(cacheFolder, cacheKey);
@@ -180,7 +178,7 @@ export class CachedExtensionScanner {
}
}
private static async _scanExtensionsWithCache(hostService: IHostService, notificationService: INotificationService, environmentService: IEnvironmentService, cacheKey: string, input: ExtensionScannerInput, log: ILog): Promise<IExtensionDescription[]> {
private static async _scanExtensionsWithCache(hostService: IHostService, notificationService: INotificationService, environmentService: INativeWorkbenchEnvironmentService, cacheKey: string, input: ExtensionScannerInput, log: ILog): Promise<IExtensionDescription[]> {
if (input.devMode) {
// Do not cache when running out of sources...
return ExtensionScanner.scanExtensions(input, log);
@@ -239,9 +237,8 @@ export class CachedExtensionScanner {
private static _scanInstalledExtensions(
hostService: IHostService,
notificationService: INotificationService,
environmentService: IEnvironmentService,
environmentService: INativeWorkbenchEnvironmentService,
extensionEnablementService: IWorkbenchExtensionEnablementService,
productService: IProductService,
log: ILog,
translations: Translations
): Promise<{ system: IExtensionDescription[], user: IExtensionDescription[], development: IExtensionDescription[] }> {
@@ -263,9 +260,7 @@ export class CachedExtensionScanner {
let finalBuiltinExtensions: Promise<IExtensionDescription[]> = builtinExtensions;
if (devMode) {
const builtInExtensionsFilePath = path.normalize(path.join(getPathFromAmdModule(require, ''), '..', 'build', 'builtInExtensions.json'));
const builtInExtensions = pfs.readFile(builtInExtensionsFilePath, 'utf8')
.then(raw => parseBuiltInExtensions(raw, productService.quality));
const builtInExtensions = Promise.resolve<IBuiltInExtension[]>(product.builtInExtensions || []);
const controlFilePath = path.join(os.homedir(), '.vscode-oss-dev', 'extensions', 'control.json');
const controlFile = pfs.readFile(controlFilePath, 'utf8')
@@ -325,7 +320,6 @@ interface IBuiltInExtension {
name: string;
version: string;
repo: string;
forQualities?: ReadonlyArray<string>;
}
interface IBuiltInExtensionControl {

View File

@@ -418,7 +418,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI,
extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI,
globalStorageHome: URI.file(this._environmentService.globalStorageHome),
userHome: URI.file(this._environmentService.userHome),
userHome: this._environmentService.userHome,
webviewResourceRoot: this._environmentService.webviewResourceRoot,
webviewCspSource: this._environmentService.webviewCspSource,
},

View File

@@ -30,10 +30,10 @@ export class ExtensionHostProfiler {
}
private distill(profile: Profile, extensions: IExtensionDescription[]): IExtensionHostProfile {
let searchTree = TernarySearchTree.forPaths<IExtensionDescription>();
let searchTree = TernarySearchTree.forUris<IExtensionDescription>();
for (let extension of extensions) {
if (extension.extensionLocation.scheme === Schemas.file) {
searchTree.set(URI.file(realpathSync(extension.extensionLocation.fsPath)).toString(), extension);
searchTree.set(URI.file(realpathSync(extension.extensionLocation.fsPath)), extension);
}
}
@@ -62,7 +62,7 @@ export class ExtensionHostProfiler {
} else if (segmentId === 'self' && node.callFrame.url) {
let extension: IExtensionDescription | undefined;
try {
extension = searchTree.findSubstr(URI.parse(node.callFrame.url).toString());
extension = searchTree.findSubstr(URI.parse(node.callFrame.url));
} catch {
// ignore
}

View File

@@ -6,8 +6,8 @@ import * as assert from 'assert';
import 'vs/workbench/services/keybinding/browser/keyboardLayouts/en.darwin'; // 15%
import 'vs/workbench/services/keybinding/browser/keyboardLayouts/de.darwin';
import { KeyboardLayoutContribution } from 'vs/workbench/services/keybinding/browser/keyboardLayouts/_.contribution';
import { BrowserKeyboardMapperFactoryBase } from '../../browser/keymapService';
import { KeymapInfo, IKeymapInfo } from '../../common/keymapInfo';
import { BrowserKeyboardMapperFactoryBase } from 'vs/workbench/services/keybinding/browser/keymapService';
import { KeymapInfo, IKeymapInfo } from 'vs/workbench/services/keybinding/common/keymapInfo';
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { ICommandService } from 'vs/platform/commands/common/commands';

View File

@@ -65,7 +65,6 @@ class TestEnvironmentService extends NativeWorkbenchEnvironmentService {
}
get appSettingsHome() { return this._appSettingsHome; }
}
interface Modifiers {

View File

@@ -21,6 +21,7 @@ import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/exte
import { match } from 'vs/base/common/glob';
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IRemotePathService } from 'vs/workbench/services/path/common/remotePathService';
const resourceLabelFormattersExtPoint = ExtensionsRegistry.registerExtensionPoint<ResourceLabelFormatter[]>({
extensionPoint: 'resourceLabelFormatters',
@@ -101,6 +102,7 @@ export class LabelService extends Disposable implements ILabelService {
constructor(
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
@IRemotePathService private readonly remotePathService: IRemotePathService
) {
super();
}
@@ -264,7 +266,10 @@ export class LabelService extends Disposable implements ILabelService {
}
if (formatting.tildify && !forceNoTildify) {
label = tildify(label, this.environmentService.userHome);
const userHome = this.remotePathService.userHomeSync;
if (userHome) {
label = tildify(label, userHome.fsPath);
}
}
if (formatting.authorityPrefix && resource.authority) {
label = formatting.authorityPrefix + label;

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as assert from 'assert';
import { TestEnvironmentService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestEnvironmentService, TestRemotePathService } from 'vs/workbench/test/browser/workbenchTestServices';
import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace';
import { URI } from 'vs/base/common/uri';
import { sep } from 'vs/base/common/path';
@@ -17,7 +17,7 @@ suite('URI Label', () => {
let labelService: LabelService;
setup(() => {
labelService = new LabelService(TestEnvironmentService, new TestContextService());
labelService = new LabelService(TestEnvironmentService, new TestContextService(), new TestRemotePathService(TestEnvironmentService));
});
test('file scheme', function () {

View File

@@ -9,19 +9,35 @@ import { URI } from 'vs/base/common/uri';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { Schemas } from 'vs/base/common/network';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
const REMOTE_PATH_SERVICE_ID = 'remotePath';
export const IRemotePathService = createDecorator<IRemotePathService>(REMOTE_PATH_SERVICE_ID);
export interface IRemotePathService {
_serviceBrand: undefined;
/**
* The path library to use for the target remote environment.
*/
readonly path: Promise<path.IPath>;
/**
* Converts the given path to a file URI in the remote environment.
*/
fileURI(path: string): Promise<URI>;
/**
* Resolves the user home of the remote environment if defined.
*/
readonly userHome: Promise<URI>;
/**
* Provides access to the user home of the remote environment
* if defined.
*/
readonly userHomeSync: URI | undefined;
}
/**
@@ -31,12 +47,15 @@ export class RemotePathService implements IRemotePathService {
_serviceBrand: undefined;
private _extHostOS: Promise<platform.OperatingSystem>;
private _userHomeSync: URI | undefined;
constructor(
@IRemoteAgentService private readonly remoteAgentService: IRemoteAgentService,
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService
) {
this._extHostOS = remoteAgentService.getEnvironment().then(remoteEnvironment => {
this._userHomeSync = remoteEnvironment?.userHome;
return remoteEnvironment ? remoteEnvironment.os : platform.OS;
});
}
@@ -91,9 +110,13 @@ export class RemotePathService implements IRemotePathService {
}
// local: use the userHome from environment
return URI.from({ scheme: Schemas.file, path: this.environmentService.userHome });
return this.environmentService.userHome!;
});
}
get userHomeSync(): URI | undefined {
return this._userHomeSync || this.environmentService.userHome;
}
}
registerSingleton(IRemotePathService, RemotePathService, true);

View File

@@ -380,11 +380,25 @@ export class ProgressService extends Disposable implements IProgressService {
const listener = progressStateModel.onDidReport(step => updateNotification(step));
Event.once(progressStateModel.onDispose)(() => listener.dispose());
// Show progress for at least 800ms and then hide once done or canceled
Promise.all([timeout(800), progressStateModel.promise]).finally(() => {
clearTimeout(notificationTimeout);
notificationHandle?.close();
});
// Clean up eventually
(async () => {
try {
// with a delay we only wait for the finish of the promise
if (typeof options.delay === 'number' && options.delay > 0) {
await progressStateModel.promise;
}
// without a delay we show the notification for at least 800ms
// to reduce the chance of the notification flashing up and hiding
else {
await Promise.all([timeout(800), progressStateModel.promise]);
}
} finally {
clearTimeout(notificationTimeout);
notificationHandle?.close();
}
})();
return progressStateModel.promise;
}

View File

@@ -7,7 +7,6 @@ import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
@@ -22,7 +21,6 @@ export class QuickInputService extends BaseQuickInputService {
private readonly inQuickInputContext = InQuickPickContextKey.bindTo(this.contextKeyService);
constructor(
@IEnvironmentService private readonly environmentService: IEnvironmentService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IInstantiationService instantiationService: IInstantiationService,
@IKeybindingService private readonly keybindingService: IKeybindingService,
@@ -43,7 +41,7 @@ export class QuickInputService extends BaseQuickInputService {
protected createController(): QuickInputController {
return super.createController(this.layoutService, {
ignoreFocusOut: () => this.environmentService.args['sticky-quickinput'] || !this.configurationService.getValue('workbench.quickOpen.closeOnFocusLost'),
ignoreFocusOut: () => !this.configurationService.getValue('workbench.quickOpen.closeOnFocusLost'),
backKeybindingLabel: () => this.keybindingService.lookupKeybinding('workbench.action.quickInputBack')?.getLabel() || undefined,
});
}

View File

@@ -3,8 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IWindowConfiguration } from 'vs/platform/windows/common/windows';
import { IRemoteAgentConnection, IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver';
import product from 'vs/platform/product/common/product';
@@ -13,6 +11,7 @@ import { AbstractRemoteAgentService, RemoteAgentConnection } from 'vs/workbench/
import { ISignService } from 'vs/platform/sign/common/sign';
import { ISocketFactory } from 'vs/platform/remote/common/remoteAgentConnection';
import { ILogService } from 'vs/platform/log/common/log';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
export class RemoteAgentService extends AbstractRemoteAgentService implements IRemoteAgentService {
@@ -20,16 +19,16 @@ export class RemoteAgentService extends AbstractRemoteAgentService implements IR
private readonly _connection: IRemoteAgentConnection | null = null;
constructor({ remoteAuthority }: IWindowConfiguration,
@IEnvironmentService environmentService: IEnvironmentService,
constructor(
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,
@IRemoteAuthorityResolverService remoteAuthorityResolverService: IRemoteAuthorityResolverService,
@ISignService signService: ISignService,
@ILogService logService: ILogService
) {
super(environmentService);
this.socketFactory = nodeSocketFactory;
if (remoteAuthority) {
this._connection = this._register(new RemoteAgentConnection(remoteAuthority, product.commit, nodeSocketFactory, remoteAuthorityResolverService, signService, logService));
if (environmentService.configuration.remoteAuthority) {
this._connection = this._register(new RemoteAgentConnection(environmentService.configuration.remoteAuthority, product.commit, nodeSocketFactory, remoteAuthorityResolverService, signService, logService));
}
}

View File

@@ -12,8 +12,8 @@ import { URI as uri } from 'vs/base/common/uri';
import { getNextTickChannel } from 'vs/base/parts/ipc/common/ipc';
import { Client, IIPCOptions } from 'vs/base/parts/ipc/node/ipc.cp';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IDebugParams } from 'vs/platform/environment/common/environment';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IDebugParams, IEnvironmentService } from 'vs/platform/environment/common/environment';
import { parseSearchPort, INativeEnvironmentService } from 'vs/platform/environment/node/environmentService';
import { IFileService } from 'vs/platform/files/common/files';
import { ILogService } from 'vs/platform/log/common/log';
import { FileMatch, IFileMatch, IFileQuery, IProgressMessage, IRawSearchService, ISearchComplete, ISearchConfiguration, ISearchProgressItem, ISearchResultProvider, ISerializedFileMatch, ISerializedSearchComplete, ISerializedSearchProgressItem, isSerializedSearchComplete, isSerializedSearchSuccess, ITextQuery, ISearchService, isFileMatch } from 'vs/workbench/services/search/common/search';
@@ -25,7 +25,6 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { parseSearchPort } from 'vs/platform/environment/node/environmentService';
export class LocalSearchService extends SearchService {
constructor(
@@ -35,12 +34,11 @@ export class LocalSearchService extends SearchService {
@ILogService logService: ILogService,
@IExtensionService extensionService: IExtensionService,
@IFileService fileService: IFileService,
@IWorkbenchEnvironmentService readonly environmentService: IWorkbenchEnvironmentService,
@IEnvironmentService readonly environmentService: INativeEnvironmentService,
@IInstantiationService readonly instantiationService: IInstantiationService
) {
super(modelService, editorService, telemetryService, logService, extensionService, fileService);
this.diskSearch = instantiationService.createInstance(DiskSearch, !environmentService.isBuilt || environmentService.verbose, parseSearchPort(environmentService.args, environmentService.isBuilt));
}
}

View File

@@ -35,7 +35,7 @@ export class TelemetryService extends Disposable implements ITelemetryService {
) {
super();
if (!environmentService.isExtensionDevelopment && !environmentService.args['disable-telemetry'] && !!productService.enableTelemetry) {
if (!environmentService.isExtensionDevelopment && !environmentService.disableTelemetry && !!productService.enableTelemetry) {
const channel = sharedProcessService.getChannel('telemetryAppender');
const config: ITelemetryServiceConfig = {
appender: combinedAppender(new TelemetryAppenderClient(channel), new LogAppender(logService)),

View File

@@ -33,7 +33,6 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IModelService } from 'vs/editor/common/services/modelService';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IDialogService, IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
import { assign } from 'vs/base/common/objects';
import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { ITextModelService } from 'vs/editor/common/services/resolverService';
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
@@ -75,16 +74,15 @@ export class NativeTextFileService extends AbstractTextFileService {
}
async read(resource: URI, options?: IReadTextFileOptions): Promise<ITextFileContent> {
const [bufferStream, decoder] = await this.doRead(resource,
assign({
// optimization: since we know that the caller does not
// care about buffering, we indicate this to the reader.
// this reduces all the overhead the buffered reading
// has (open, read, close) if the provider supports
// unbuffered reading.
preferUnbuffered: true
}, options || Object.create(null))
);
const [bufferStream, decoder] = await this.doRead(resource, {
...options,
// optimization: since we know that the caller does not
// care about buffering, we indicate this to the reader.
// this reduces all the overhead the buffered reading
// has (open, read, close) if the provider supports
// unbuffered reading.
preferUnbuffered: true
});
return {
...bufferStream,

View File

@@ -120,7 +120,7 @@ const schema: IJSONSchema = {
properties: {
path: {
type: 'string',
description: nls.localize('schema.font-path', 'The font path, relative to the current icon theme file.'),
description: nls.localize('schema.font-path', 'The font path, relative to the current file icon theme file.'),
},
format: {
type: 'string',

View File

@@ -34,7 +34,7 @@ const schema: IJSONSchema = {
properties: {
path: {
type: 'string',
description: nls.localize('schema.font-path', 'The font path, relative to the current workbench icon theme file.'),
description: nls.localize('schema.font-path', 'The font path, relative to the current product icon theme file.'),
},
format: {
type: 'string',

View File

@@ -89,10 +89,10 @@ const fileIconThemeSettingSchema: IConfigurationPropertySchema = {
const productIconThemeSettingSchema: IConfigurationPropertySchema = {
type: ['string', 'null'],
default: DEFAULT_PRODUCT_ICON_THEME_SETTING_VALUE,
description: nls.localize('workbenchIconTheme', "Specifies the workbench icon theme used."),
description: nls.localize('productIconTheme', "Specifies the product icon theme used."),
enum: [DEFAULT_PRODUCT_ICON_THEME_SETTING_VALUE],
enumDescriptions: [nls.localize('defaultWorkbenchIconThemeDesc', 'Default')],
errorMessage: nls.localize('workbenchIconThemeError', "Workbench icon theme is unknown or not installed.")
enumDescriptions: [nls.localize('defaultProductIconThemeDesc', 'Default')],
errorMessage: nls.localize('productIconThemeError', "Product icon theme is unknown or not installed.")
};
const themeSettingsConfiguration: IConfigurationNode = {

View File

@@ -23,6 +23,7 @@ import { mnemonicButtonLabel } from 'vs/base/common/labels';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { Schemas } from 'vs/base/common/network';
export abstract class AbstractWorkspaceEditingService implements IWorkspaceEditingService {
@@ -127,13 +128,10 @@ export abstract class AbstractWorkspaceEditingService implements IWorkspaceEditi
private async doAddFolders(foldersToAdd: IWorkspaceFolderCreationData[], index?: number, donotNotifyError: boolean = false): Promise<void> {
const state = this.contextService.getWorkbenchState();
if (this.environmentService.configuration.remoteAuthority) {
// Do not allow workspace folders with scheme different than the current remote scheme
const schemas = this.contextService.getWorkspace().folders.map(f => f.uri.scheme);
if (schemas.length && foldersToAdd.some(f => schemas.indexOf(f.uri.scheme) === -1)) {
throw new Error(nls.localize('differentSchemeRoots', "Workspace folders from different providers are not allowed in the same workspace."));
}
const remoteAuthority = this.environmentService.configuration.remoteAuthority;
if (remoteAuthority) {
// https://github.com/microsoft/vscode/issues/94191
foldersToAdd = foldersToAdd.filter(f => f.uri.scheme !== Schemas.file && (f.uri.scheme !== Schemas.vscodeRemote || f.uri.authority === remoteAuthority));
}
// If we are in no-workspace or single-folder workspace, adding folders has to