Merge from vscode 2cfc8172e533e50c90e6a3152f6bfb1f82f963f3 (#6516)

* Merge from vscode 2cfc8172e533e50c90e6a3152f6bfb1f82f963f3

* fix tests
This commit is contained in:
Anthony Dresser
2019-07-28 15:15:24 -07:00
committed by GitHub
parent aacf1e7f1c
commit 1d56a17f32
292 changed files with 19784 additions and 1873 deletions

View File

@@ -5,19 +5,23 @@
import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
import { isWindows } from 'vs/base/common/platform';
import { Emitter, Event } from 'vs/base/common/event';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { AbstractAccessibilityService } from 'vs/platform/accessibility/common/abstractAccessibilityService';
export class AccessibilityService implements IAccessibilityService {
export class AccessibilityService extends AbstractAccessibilityService implements IAccessibilityService {
_serviceBrand: any;
private _accessibilitySupport = AccessibilitySupport.Unknown;
private readonly _onDidChangeAccessibilitySupport = new Emitter<void>();
readonly onDidChangeAccessibilitySupport: Event<void> = this._onDidChangeAccessibilitySupport.event;
constructor(
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService
) { }
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
@IContextKeyService readonly contextKeyService: IContextKeyService,
@IConfigurationService readonly configurationService: IConfigurationService
) {
super(contextKeyService, configurationService);
}
alwaysUnderlineAccessKeys(): Promise<boolean> {
if (!isWindows) {

View File

@@ -22,6 +22,9 @@ export class CommandService extends Disposable implements ICommandService {
private readonly _onWillExecuteCommand: Emitter<ICommandEvent> = this._register(new Emitter<ICommandEvent>());
public readonly onWillExecuteCommand: Event<ICommandEvent> = this._onWillExecuteCommand.event;
private readonly _onDidExecuteCommand: Emitter<ICommandEvent> = new Emitter<ICommandEvent>();
public readonly onDidExecuteCommand: Event<ICommandEvent> = this._onDidExecuteCommand.event;
constructor(
@IInstantiationService private readonly _instantiationService: IInstantiationService,
@IExtensionService private readonly _extensionService: IExtensionService,
@@ -77,8 +80,9 @@ export class CommandService extends Disposable implements ICommandService {
return Promise.reject(new Error(`command '${id}' not found`));
}
try {
this._onWillExecuteCommand.fire({ commandId: id });
this._onWillExecuteCommand.fire({ commandId: id, args });
const result = this._instantiationService.invokeFunction.apply(this._instantiationService, [command.handler, ...args]);
this._onDidExecuteCommand.fire({ commandId: id, args });
return Promise.resolve(result);
} catch (err) {
return Promise.reject(err);

View File

@@ -12,7 +12,7 @@ import { RunOnceScheduler } from 'vs/base/common/async';
import { FileChangeType, FileChangesEvent, IFileService } from 'vs/platform/files/common/files';
import { ConfigurationModel, ConfigurationModelParser } from 'vs/platform/configuration/common/configurationModels';
import { WorkspaceConfigurationModelParser, StandaloneConfigurationModelParser } from 'vs/workbench/services/configuration/common/configurationModels';
import { FOLDER_SETTINGS_PATH, TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES, ConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration';
import { FOLDER_SETTINGS_PATH, TASKS_CONFIGURATION_KEY, FOLDER_SETTINGS_NAME, LAUNCH_CONFIGURATION_KEY, IConfigurationCache, ConfigurationKey, REMOTE_MACHINE_SCOPES, FOLDER_SCOPES, WORKSPACE_SCOPES } from 'vs/workbench/services/configuration/common/configuration';
import { IStoredWorkspaceFolder, IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces';
import { JSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditingService';
import { WorkbenchState, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
@@ -24,6 +24,20 @@ import { IConfigurationModel } from 'vs/platform/configuration/common/configurat
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { hash } from 'vs/base/common/hash';
function whenProviderRegistered(scheme: string, fileService: IFileService): Promise<void> {
if (fileService.canHandleResource(URI.from({ scheme }))) {
return Promise.resolve();
}
return new Promise((c, e) => {
const disposable = fileService.onDidChangeFileSystemProviderRegistrations(e => {
if (e.scheme === scheme && e.added) {
disposable.dispose();
c();
}
});
});
}
export class UserConfiguration extends Disposable {
private readonly parser: ConfigurationModelParser;
@@ -66,7 +80,7 @@ export class UserConfiguration extends Disposable {
export class RemoteUserConfiguration extends Disposable {
private readonly _cachedConfiguration: CachedRemoteUserConfiguration;
private readonly _configurationFileService: ConfigurationFileService;
private readonly _fileService: IFileService;
private _userConfiguration: FileServiceBasedRemoteUserConfiguration | CachedRemoteUserConfiguration;
private _userConfigurationInitializationPromise: Promise<ConfigurationModel> | null = null;
@@ -76,15 +90,15 @@ export class RemoteUserConfiguration extends Disposable {
constructor(
remoteAuthority: string,
configurationCache: IConfigurationCache,
configurationFileService: ConfigurationFileService,
fileService: IFileService,
remoteAgentService: IRemoteAgentService
) {
super();
this._configurationFileService = configurationFileService;
this._fileService = fileService;
this._userConfiguration = this._cachedConfiguration = new CachedRemoteUserConfiguration(remoteAuthority, configurationCache);
remoteAgentService.getEnvironment().then(async environment => {
if (environment) {
const userConfiguration = this._register(new FileServiceBasedRemoteUserConfiguration(environment.settingsPath, REMOTE_MACHINE_SCOPES, this._configurationFileService));
const userConfiguration = this._register(new FileServiceBasedRemoteUserConfiguration(environment.settingsPath, REMOTE_MACHINE_SCOPES, this._fileService));
this._register(userConfiguration.onDidChangeConfiguration(configurationModel => this.onDidUserConfigurationChange(configurationModel)));
this._userConfigurationInitializationPromise = userConfiguration.initialize();
const configurationModel = await this._userConfigurationInitializationPromise;
@@ -142,12 +156,12 @@ class FileServiceBasedRemoteUserConfiguration extends Disposable {
constructor(
private readonly configurationResource: URI,
private readonly scopes: ConfigurationScope[] | undefined,
private readonly configurationFileService: ConfigurationFileService
private readonly fileService: IFileService
) {
super();
this.parser = new ConfigurationModelParser(this.configurationResource.toString(), this.scopes);
this._register(configurationFileService.onFileChanges(e => this.handleFileEvents(e)));
this._register(fileService.onFileChanges(e => this.handleFileEvents(e)));
this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reload().then(configurationModel => this._onDidChangeConfiguration.fire(configurationModel)), 50));
this._register(toDisposable(() => {
this.stopWatchingResource();
@@ -156,7 +170,7 @@ class FileServiceBasedRemoteUserConfiguration extends Disposable {
}
private watchResource(): void {
this.fileWatcherDisposable = this.configurationFileService.watch(this.configurationResource);
this.fileWatcherDisposable = this.fileService.watch(this.configurationResource);
}
private stopWatchingResource(): void {
@@ -166,7 +180,7 @@ class FileServiceBasedRemoteUserConfiguration extends Disposable {
private watchDirectory(): void {
const directory = resources.dirname(this.configurationResource);
this.directoryWatcherDisposable = this.configurationFileService.watch(directory);
this.directoryWatcherDisposable = this.fileService.watch(directory);
}
private stopWatchingDirectory(): void {
@@ -175,15 +189,15 @@ class FileServiceBasedRemoteUserConfiguration extends Disposable {
}
async initialize(): Promise<ConfigurationModel> {
const exists = await this.configurationFileService.exists(this.configurationResource);
const exists = await this.fileService.exists(this.configurationResource);
this.onResourceExists(exists);
return this.reload();
}
async reload(): Promise<ConfigurationModel> {
try {
const content = await this.configurationFileService.readFile(this.configurationResource);
this.parser.parseContent(content);
const content = await this.fileService.readFile(this.configurationResource);
this.parser.parseContent(content.value.toString());
return this.parser.configurationModel;
} catch (e) {
return new ConfigurationModel();
@@ -279,7 +293,7 @@ class CachedRemoteUserConfiguration extends Disposable {
export class WorkspaceConfiguration extends Disposable {
private readonly _configurationFileService: ConfigurationFileService;
private readonly _fileService: IFileService;
private readonly _cachedConfiguration: CachedWorkspaceConfiguration;
private _workspaceConfiguration: IWorkspaceConfiguration;
private _workspaceConfigurationChangeDisposable: IDisposable = Disposable.None;
@@ -293,10 +307,10 @@ export class WorkspaceConfiguration extends Disposable {
constructor(
configurationCache: IConfigurationCache,
configurationFileService: ConfigurationFileService
fileService: IFileService
) {
super();
this._configurationFileService = configurationFileService;
this._fileService = fileService;
this._workspaceConfiguration = this._cachedConfiguration = new CachedWorkspaceConfiguration(configurationCache);
}
@@ -304,7 +318,7 @@ export class WorkspaceConfiguration extends Disposable {
this._workspaceIdentifier = workspaceIdentifier;
if (!(this._workspaceConfiguration instanceof FileServiceBasedWorkspaceConfiguration)) {
if (this._workspaceIdentifier.configPath.scheme === Schemas.file) {
this.switch(new FileServiceBasedWorkspaceConfiguration(this._configurationFileService));
this.switch(new FileServiceBasedWorkspaceConfiguration(this._fileService));
} else {
this.waitAndSwitch(this._workspaceIdentifier);
}
@@ -339,9 +353,9 @@ export class WorkspaceConfiguration extends Disposable {
}
private async waitAndSwitch(workspaceIdentifier: IWorkspaceIdentifier): Promise<void> {
await this._configurationFileService.whenProviderRegistered(workspaceIdentifier.configPath.scheme);
await whenProviderRegistered(workspaceIdentifier.configPath.scheme, this._fileService);
if (!(this._workspaceConfiguration instanceof FileServiceBasedWorkspaceConfiguration)) {
const fileServiceBasedWorkspaceConfiguration = this._register(new FileServiceBasedWorkspaceConfiguration(this._configurationFileService));
const fileServiceBasedWorkspaceConfiguration = this._register(new FileServiceBasedWorkspaceConfiguration(this._fileService));
await fileServiceBasedWorkspaceConfiguration.load(workspaceIdentifier);
this.switch(fileServiceBasedWorkspaceConfiguration);
this._loaded = true;
@@ -396,13 +410,13 @@ class FileServiceBasedWorkspaceConfiguration extends Disposable implements IWork
protected readonly _onDidChange: Emitter<void> = this._register(new Emitter<void>());
readonly onDidChange: Event<void> = this._onDidChange.event;
constructor(private configurationFileService: ConfigurationFileService) {
constructor(private fileService: IFileService) {
super();
this.workspaceConfigurationModelParser = new WorkspaceConfigurationModelParser('');
this.workspaceSettings = new ConfigurationModel();
this._register(configurationFileService.onFileChanges(e => this.handleWorkspaceFileEvents(e)));
this._register(fileService.onFileChanges(e => this.handleWorkspaceFileEvents(e)));
this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this._onDidChange.fire(), 50));
this.workspaceConfigWatcher = this._register(this.watchWorkspaceConfigurationFile());
}
@@ -420,9 +434,10 @@ class FileServiceBasedWorkspaceConfiguration extends Disposable implements IWork
}
let contents = '';
try {
contents = await this.configurationFileService.readFile(this._workspaceIdentifier.configPath);
const content = await this.fileService.readFile(this._workspaceIdentifier.configPath);
contents = content.value.toString();
} catch (error) {
const exists = await this.configurationFileService.exists(this._workspaceIdentifier.configPath);
const exists = await this.fileService.exists(this._workspaceIdentifier.configPath);
if (exists) {
errors.onUnexpectedError(error);
}
@@ -454,7 +469,7 @@ class FileServiceBasedWorkspaceConfiguration extends Disposable implements IWork
}
private watchWorkspaceConfigurationFile(): IDisposable {
return this._workspaceIdentifier ? this.configurationFileService.watch(this._workspaceIdentifier.configPath) : Disposable.None;
return this._workspaceIdentifier ? this.fileService.watch(this._workspaceIdentifier.configPath) : Disposable.None;
}
private handleWorkspaceFileEvents(event: FileChangesEvent): void {
@@ -557,7 +572,7 @@ class FileServiceBasedFolderConfiguration extends Disposable implements IFolderC
protected readonly _onDidChange: Emitter<void> = this._register(new Emitter<void>());
readonly onDidChange: Event<void> = this._onDidChange.event;
constructor(protected readonly configurationFolder: URI, workbenchState: WorkbenchState, private configurationFileService: ConfigurationFileService) {
constructor(protected readonly configurationFolder: URI, workbenchState: WorkbenchState, private fileService: IFileService) {
super();
this.configurationNames = [FOLDER_SETTINGS_NAME /*First one should be settings */, TASKS_CONFIGURATION_KEY, LAUNCH_CONFIGURATION_KEY];
@@ -567,15 +582,16 @@ class FileServiceBasedFolderConfiguration extends Disposable implements IFolderC
this._cache = new ConfigurationModel();
this.changeEventTriggerScheduler = this._register(new RunOnceScheduler(() => this._onDidChange.fire(), 50));
this._register(configurationFileService.onFileChanges(e => this.handleWorkspaceFileEvents(e)));
this._register(fileService.onFileChanges(e => this.handleWorkspaceFileEvents(e)));
}
async loadConfiguration(): Promise<ConfigurationModel> {
const configurationContents = await Promise.all(this.configurationResources.map(async resource => {
try {
return await this.configurationFileService.readFile(resource);
const content = await this.fileService.readFile(resource);
return content.value.toString();
} catch (error) {
const exists = await this.configurationFileService.exists(resource);
const exists = await this.fileService.exists(resource);
if (exists) {
errors.onUnexpectedError(error);
}
@@ -724,7 +740,7 @@ export class FolderConfiguration extends Disposable implements IFolderConfigurat
readonly workspaceFolder: IWorkspaceFolder,
configFolderRelativePath: string,
private readonly workbenchState: WorkbenchState,
configurationFileService: ConfigurationFileService,
fileService: IFileService,
configurationCache: IConfigurationCache
) {
super();
@@ -732,13 +748,13 @@ export class FolderConfiguration extends Disposable implements IFolderConfigurat
this.configurationFolder = resources.joinPath(workspaceFolder.uri, configFolderRelativePath);
this.folderConfiguration = this.cachedFolderConfiguration = new CachedFolderConfiguration(workspaceFolder.uri, configFolderRelativePath, configurationCache);
if (workspaceFolder.uri.scheme === Schemas.file) {
this.folderConfiguration = new FileServiceBasedFolderConfiguration(this.configurationFolder, this.workbenchState, configurationFileService);
this.folderConfiguration = new FileServiceBasedFolderConfiguration(this.configurationFolder, this.workbenchState, fileService);
} else {
configurationFileService.whenProviderRegistered(workspaceFolder.uri.scheme)
whenProviderRegistered(workspaceFolder.uri.scheme, fileService)
.then(() => {
this.folderConfiguration.dispose();
this.folderConfigurationDisposable.dispose();
this.folderConfiguration = new FileServiceBasedFolderConfiguration(this.configurationFolder, this.workbenchState, configurationFileService);
this.folderConfiguration = new FileServiceBasedFolderConfiguration(this.configurationFolder, this.workbenchState, fileService);
this._register(this.folderConfiguration.onDidChange(e => this.onDidFolderConfigurationChange()));
this.onDidFolderConfigurationChange();
});

View File

@@ -14,7 +14,7 @@ import { IWorkspaceContextService, Workspace, WorkbenchState, IWorkspaceFolder,
import { ConfigurationChangeEvent, ConfigurationModel, DefaultConfigurationModel } from 'vs/platform/configuration/common/configurationModels';
import { IConfigurationChangeEvent, ConfigurationTarget, IConfigurationOverrides, keyFromOverrideIdentifier, isConfigurationOverrides, IConfigurationData, IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { Configuration, WorkspaceConfigurationChangeEvent, AllKeysConfigurationChangeEvent } from 'vs/workbench/services/configuration/common/configurationModels';
import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES, ConfigurationFileService } from 'vs/workbench/services/configuration/common/configuration';
import { FOLDER_CONFIG_FOLDER_NAME, defaultSettingsSchemaId, userSettingsSchemaId, workspaceSettingsSchemaId, folderSettingsSchemaId, IConfigurationCache, machineSettingsSchemaId, LOCAL_MACHINE_SCOPES } from 'vs/workbench/services/configuration/common/configuration';
import { Registry } from 'vs/platform/registry/common/platform';
import { IConfigurationRegistry, Extensions, allSettings, windowSettings, resourceSettings, applicationSettings, machineSettings } from 'vs/platform/configuration/common/configurationRegistry';
import { IWorkspaceIdentifier, isWorkspaceIdentifier, IStoredWorkspaceFolder, isStoredWorkspaceFolder, IWorkspaceFolderCreationData, ISingleFolderWorkspaceIdentifier, isSingleFolderWorkspaceIdentifier, IWorkspaceInitializationPayload, isSingleFolderWorkspaceInitializationPayload, ISingleFolderWorkspaceInitializationPayload, IEmptyWorkspaceInitializationPayload, useSlashForPath, getStoredWorkspaceFolder } from 'vs/platform/workspaces/common/workspaces';
@@ -45,7 +45,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
private cachedFolderConfigs: ResourceMap<FolderConfiguration>;
private workspaceEditingQueue: Queue<void>;
private readonly configurationFileService: ConfigurationFileService;
private readonly fileService: IFileService;
protected readonly _onDidChangeConfiguration: Emitter<IConfigurationChangeEvent> = this._register(new Emitter<IConfigurationChangeEvent>());
public readonly onDidChangeConfiguration: Event<IConfigurationChangeEvent> = this._onDidChangeConfiguration.event;
@@ -76,16 +76,16 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
this.completeWorkspaceBarrier = new Barrier();
this.defaultConfiguration = new DefaultConfigurationModel();
this.configurationCache = configurationCache;
this.configurationFileService = new ConfigurationFileService(fileService);
this.fileService = fileService;
this._configuration = new Configuration(this.defaultConfiguration, new ConfigurationModel(), new ConfigurationModel(), new ConfigurationModel(), new ResourceMap(), new ConfigurationModel(), new ResourceMap<ConfigurationModel>(), this.workspace);
this.cachedFolderConfigs = new ResourceMap<FolderConfiguration>();
this.localUserConfiguration = this._register(new UserConfiguration(environmentService.settingsResource, remoteAuthority ? LOCAL_MACHINE_SCOPES : undefined, fileService));
this._register(this.localUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onLocalUserConfigurationChanged(userConfiguration)));
if (remoteAuthority) {
this.remoteUserConfiguration = this._register(new RemoteUserConfiguration(remoteAuthority, configurationCache, this.configurationFileService, remoteAgentService));
this.remoteUserConfiguration = this._register(new RemoteUserConfiguration(remoteAuthority, configurationCache, fileService, remoteAgentService));
this._register(this.remoteUserConfiguration.onDidChangeConfiguration(userConfiguration => this.onRemoteUserConfigurationChanged(userConfiguration)));
}
this.workspaceConfiguration = this._register(new WorkspaceConfiguration(configurationCache, this.configurationFileService));
this.workspaceConfiguration = this._register(new WorkspaceConfiguration(configurationCache, fileService));
this._register(this.workspaceConfiguration.onDidUpdateConfiguration(() => {
this.onWorkspaceConfigurationChanged();
if (this.workspaceConfiguration.loaded) {
@@ -610,7 +610,7 @@ export class WorkspaceService extends Disposable implements IConfigurationServic
return Promise.all([...folders.map(folder => {
let folderConfiguration = this.cachedFolderConfigs.get(folder.uri);
if (!folderConfiguration) {
folderConfiguration = new FolderConfiguration(folder, FOLDER_CONFIG_FOLDER_NAME, this.getWorkbenchState(), this.configurationFileService, this.configurationCache);
folderConfiguration = new FolderConfiguration(folder, FOLDER_CONFIG_FOLDER_NAME, this.getWorkbenchState(), this.fileService, this.configurationCache);
this._register(folderConfiguration.onDidChange(() => this.onWorkspaceFolderConfigurationChanged(folder)));
this.cachedFolderConfigs.set(folder.uri, this._register(folderConfiguration));
}

View File

@@ -3,9 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { URI } from 'vs/base/common/uri';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IFileService } from 'vs/platform/files/common/files';
import { ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
export const FOLDER_CONFIG_FOLDER_NAME = '.azuredatastudio';
@@ -39,38 +36,4 @@ export interface IConfigurationCache {
write(key: ConfigurationKey, content: string): Promise<void>;
remove(key: ConfigurationKey): Promise<void>;
}
export class ConfigurationFileService {
constructor(private readonly fileService: IFileService) { }
get onFileChanges() { return this.fileService.onFileChanges; }
whenProviderRegistered(scheme: string): Promise<void> {
if (this.fileService.canHandleResource(URI.from({ scheme }))) {
return Promise.resolve();
}
return new Promise((c, e) => {
const disposable = this.fileService.onDidChangeFileSystemProviderRegistrations(e => {
if (e.scheme === scheme && e.added) {
disposable.dispose();
c();
}
});
});
}
watch(resource: URI): IDisposable {
return this.fileService.watch(resource);
}
exists(resource: URI): Promise<boolean> {
return this.fileService.exists(resource);
}
readFile(resource: URI): Promise<string> {
return this.fileService.readFile(resource).then(content => content.value.toString());
}
}
}

View File

@@ -227,6 +227,10 @@ export abstract class BaseConfigurationResolverService extends AbstractVariableR
*/
private showUserInput(variable: string, inputInfos: ConfiguredInput[]): Promise<string | undefined> {
if (!inputInfos) {
return Promise.reject(new Error(nls.localize('inputVariable.noInputSection', "Variable '{0}' must be defined in an '{1}' section of the debug or task configuration.", variable, 'input')));
}
// find info for the given input variable
const info = inputInfos.filter(item => item.id === variable).pop();
if (info) {
@@ -307,4 +311,4 @@ export class ConfigurationResolverService extends BaseConfigurationResolverServi
}
}
registerSingleton(IConfigurationResolverService, ConfigurationResolverService, true);
registerSingleton(IConfigurationResolverService, ConfigurationResolverService, true);

View File

@@ -523,6 +523,7 @@ class MockCommandService implements ICommandService {
public callCount = 0;
onWillExecuteCommand = () => Disposable.None;
onDidExecuteCommand = () => Disposable.None;
public executeCommand(commandId: string, ...args: any[]): Promise<any> {
this.callCount++;

View File

@@ -179,7 +179,7 @@ export interface IEditorGroupsService {
/**
* The size of the editor groups area.
*/
readonly dimension: IDimension;
readonly contentDimension: IDimension;
/**
* An active group is the default location for new editors to open.

View File

@@ -130,7 +130,11 @@ export class ExtensionManagementService extends Disposable implements IExtension
}
zip(extension: ILocalExtension): Promise<URI> {
throw new Error('Not Supported');
const server = this.getServer(extension);
if (server) {
return server.extensionManagementService.zip(extension);
}
return Promise.reject(`Invalid location ${extension.location.toString()}`);
}
unzip(zipLocation: URI, type: ExtensionType): Promise<IExtensionIdentifier> {

View File

@@ -14,7 +14,6 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IFileService } from 'vs/platform/files/common/files';
import { IProductService } from 'vs/platform/product/common/product';
import { AbstractExtensionService } from 'vs/workbench/services/extensions/common/abstractExtensionService';
import { browserWebSocketFactory } from 'vs/platform/remote/browser/browserWebSocketFactory';
import { ExtensionHostProcessManager } from 'vs/workbench/services/extensions/common/extensionHostProcessManager';
import { RemoteExtensionHostClient, IInitDataProvider } from 'vs/workbench/services/extensions/common/remoteExtensionHostClient';
import { IRemoteAgentEnvironment } from 'vs/platform/remote/common/remoteAgentEnvironment';
@@ -63,7 +62,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
const result: ExtensionHostProcessManager[] = [];
const remoteAgentConnection = this._remoteAgentService.getConnection()!;
const remoteExtHostProcessWorker = this._instantiationService.createInstance(RemoteExtensionHostClient, this.getExtensions(), this._createProvider(remoteAgentConnection.remoteAuthority), browserWebSocketFactory);
const remoteExtHostProcessWorker = this._instantiationService.createInstance(RemoteExtensionHostClient, this.getExtensions(), this._createProvider(remoteAgentConnection.remoteAuthority), this._remoteAgentService.socketFactory);
const remoteExtHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, remoteExtHostProcessWorker, remoteAgentConnection.remoteAuthority, initialActivationEvents);
result.push(remoteExtHostProcessManager);

View File

@@ -7,6 +7,7 @@ import { localize } from 'vs/nls';
import { Action } from 'vs/base/common/actions';
import { IDisposable, toDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
import { IExtensionGalleryService, IExtensionIdentifier, IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { IExtensionEnablementService, EnablementState } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
@@ -23,6 +24,8 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
const FIVE_MINUTES = 5 * 60 * 1000;
const THIRTY_SECONDS = 30 * 1000;
const URL_TO_HANDLE = 'extensionUrlHandler.urlToHandle';
const CONFIRMED_EXTENSIONS_CONFIGURATION_KEY = 'extensions.confirmedUriHandlerExtensionIds';
const CONFIRMED_EXTENSIONS_STORAGE_KEY = 'extensionUrlHandler.confirmedExtensions';
function isExtensionId(value: string): boolean {
return /^[a-z0-9][a-z0-9\-]*\.[a-z0-9][a-z0-9\-]*$/i.test(value);
@@ -62,7 +65,9 @@ export class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler {
@IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService,
@IWindowService private readonly windowService: IWindowService,
@IExtensionGalleryService private readonly galleryService: IExtensionGalleryService,
@IStorageService private readonly storageService: IStorageService
@IStorageService private readonly storageService: IStorageService,
@IConfigurationService private readonly configurationService: IConfigurationService
) {
const interval = setInterval(() => this.garbageCollect(), THIRTY_SECONDS);
const urlToHandleValue = this.storageService.get(URL_TO_HANDLE, StorageScope.WORKSPACE);
@@ -91,6 +96,11 @@ export class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler {
return true;
}
if (!confirmed) {
const confirmedExtensionIds = this.getConfirmedExtensionIds();
confirmed = confirmedExtensionIds.has(ExtensionIdentifier.toKey(extensionId));
}
if (!confirmed) {
let uriString = uri.toString();
@@ -100,6 +110,9 @@ export class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler {
const result = await this.dialogService.confirm({
message: localize('confirmUrl', "Allow an extension to open this URL?", extensionId),
checkbox: {
label: localize('rememberConfirmUrl', "Don't ask again for this extension."),
},
detail: `${extension.displayName || extension.name} (${extensionId}) wants to open a URL:\n\n${uriString}`,
primaryButton: localize('open', "&&Open"),
type: 'question'
@@ -108,6 +121,10 @@ export class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler {
if (!result.confirmed) {
return true;
}
if (result.checkboxChecked) {
this.addConfirmedExtensionIdToStorage(extensionId);
}
}
const handler = this.extensionHandlers.get(ExtensionIdentifier.toKey(extensionId));
@@ -267,6 +284,47 @@ export class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler {
this.uriBuffer = uriBuffer;
}
private getConfirmedExtensionIds(): Set<string> {
const ids = [
...this.getConfirmedExtensionIdsFromStorage(),
...this.getConfirmedExtensionIdsFromConfiguration(),
].map(extensionId => ExtensionIdentifier.toKey(extensionId));
return new Set(ids);
}
private getConfirmedExtensionIdsFromConfiguration(): Array<string> {
const confirmedExtensionIds = this.configurationService.getValue<Array<string>>(CONFIRMED_EXTENSIONS_CONFIGURATION_KEY);
if (!Array.isArray(confirmedExtensionIds)) {
return [];
}
return confirmedExtensionIds;
}
private getConfirmedExtensionIdsFromStorage(): Array<string> {
const confirmedExtensionIdsJson = this.storageService.get(CONFIRMED_EXTENSIONS_STORAGE_KEY, StorageScope.GLOBAL, '[]');
try {
return JSON.parse(confirmedExtensionIdsJson);
} catch (err) {
return [];
}
}
private addConfirmedExtensionIdToStorage(extensionId: string): void {
const existingConfirmedExtensionIds = this.getConfirmedExtensionIdsFromStorage();
this.storageService.store(
CONFIRMED_EXTENSIONS_STORAGE_KEY,
JSON.stringify([
...existingConfirmedExtensionIds,
ExtensionIdentifier.toKey(extensionId),
]),
StorageScope.GLOBAL,
);
}
dispose(): void {
this.disposable.dispose();
this.extensionHandlers.clear();

View File

@@ -8,7 +8,7 @@ import { IMessagePassingProtocol } from 'vs/base/parts/ipc/common/ipc';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { ILabelService } from 'vs/platform/label/common/label';
import { ILogService } from 'vs/platform/log/common/log';
import { connectRemoteAgentExtensionHost, IRemoteExtensionHostStartParams, IConnectionOptions, IWebSocketFactory } from 'vs/platform/remote/common/remoteAgentConnection';
import { connectRemoteAgentExtensionHost, IRemoteExtensionHostStartParams, IConnectionOptions, ISocketFactory } from 'vs/platform/remote/common/remoteAgentConnection';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IInitData } from 'vs/workbench/api/common/extHost.protocol';
@@ -47,7 +47,7 @@ export class RemoteExtensionHostClient extends Disposable implements IExtensionH
constructor(
private readonly _allExtensions: Promise<IExtensionDescription[]>,
private readonly _initDataProvider: IInitDataProvider,
private readonly _webSocketFactory: IWebSocketFactory,
private readonly _socketFactory: ISocketFactory,
@IWorkspaceContextService private readonly _contextService: IWorkspaceContextService,
@IEnvironmentService private readonly _environmentService: IEnvironmentService,
@ITelemetryService private readonly _telemetryService: ITelemetryService,
@@ -73,7 +73,7 @@ export class RemoteExtensionHostClient extends Disposable implements IExtensionH
const options: IConnectionOptions = {
isBuilt: this._environmentService.isBuilt,
commit: this._productService.commit,
webSocketFactory: this._webSocketFactory,
socketFactory: this._socketFactory,
addressProvider: {
getAddress: async () => {
const { authority } = await this.remoteAuthorityResolverService.resolveAuthority(this._initDataProvider.remoteAuthority);

View File

@@ -7,7 +7,6 @@ import { ipcRenderer as ipc } from 'electron';
import { ExtensionHostProcessWorker } from 'vs/workbench/services/extensions/electron-browser/extensionHost';
import { CachedExtensionScanner } from 'vs/workbench/services/extensions/electron-browser/cachedExtensionScanner';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { nodeWebSocketFactory } from 'vs/platform/remote/node/nodeWebSocketFactory';
import { AbstractExtensionService } from 'vs/workbench/services/extensions/common/abstractExtensionService';
import * as nls from 'vs/nls';
import * as path from 'vs/base/common/path';
@@ -203,6 +202,8 @@ export class ExtensionService extends AbstractExtensionService implements IExten
// Update the local registry
const result = this._registry.deltaExtensions(toAdd, toRemove.map(e => e.identifier));
this._onDidChangeExtensions.fire(undefined);
toRemove = toRemove.concat(result.removedDueToLooping);
if (result.removedDueToLooping.length > 0) {
this._logOrShowMessage(Severity.Error, nls.localize('looping', "The following extensions contain dependency loops and have been disabled: {0}", result.removedDueToLooping.map(e => `'${e.identifier.value}'`).join(', ')));
@@ -219,8 +220,6 @@ export class ExtensionService extends AbstractExtensionService implements IExten
await this._extensionHostProcessManagers[0].deltaExtensions(toAdd, toRemove.map(e => e.identifier));
}
this._onDidChangeExtensions.fire(undefined);
for (let i = 0; i < toAdd.length; i++) {
this._activateAddedExtensionIfNeeded(toAdd[i]);
}
@@ -361,7 +360,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
const remoteAgentConnection = this._remoteAgentService.getConnection();
if (remoteAgentConnection) {
const remoteExtHostProcessWorker = this._instantiationService.createInstance(RemoteExtensionHostClient, this.getExtensions(), this._createProvider(remoteAgentConnection.remoteAuthority), nodeWebSocketFactory);
const remoteExtHostProcessWorker = this._instantiationService.createInstance(RemoteExtensionHostClient, this.getExtensions(), this._createProvider(remoteAgentConnection.remoteAuthority), this._remoteAgentService.socketFactory);
const remoteExtHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, remoteExtHostProcessWorker, remoteAgentConnection.remoteAuthority, initialActivationEvents);
result.push(remoteExtHostProcessManager);
}

View File

@@ -300,7 +300,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
private _resolveKeybindingItems(items: IKeybindingItem[], isDefault: boolean): ResolvedKeybindingItem[] {
let result: ResolvedKeybindingItem[] = [], resultLen = 0;
for (const item of items) {
const when = (item.when ? item.when.normalize() : undefined);
const when = item.when || undefined;
const keybinding = item.keybinding;
if (!keybinding) {
// This might be a removal keybinding item in user settings => accept it
@@ -323,7 +323,7 @@ export class WorkbenchKeybindingService extends AbstractKeybindingService {
private _resolveUserKeybindingItems(items: IUserKeybindingItem[], isDefault: boolean): ResolvedKeybindingItem[] {
let result: ResolvedKeybindingItem[] = [], resultLen = 0;
for (const item of items) {
const when = (item.when ? item.when.normalize() : undefined);
const when = item.when || undefined;
const parts = item.parts;
if (parts.length === 0) {
// This might be a removal keybinding item in user settings => accept it

View File

@@ -8,6 +8,7 @@ import { Event } from 'vs/base/common/event';
import { MenuBarVisibility } from 'vs/platform/windows/common/windows';
import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
import { Part } from 'vs/workbench/browser/part';
import { Dimension } from 'vs/base/browser/dom';
export const IWorkbenchLayoutService = createDecorator<IWorkbenchLayoutService>('layoutService');
@@ -81,6 +82,11 @@ export interface IWorkbenchLayoutService extends ILayoutService {
*/
isVisible(part: Parts): boolean;
/**
* Returns if the part is visible.
*/
getDimension(part: Parts): Dimension;
/**
* Set activity bar hidden or not
*/

View File

@@ -91,11 +91,15 @@ export class PreferencesService extends Disposable implements IPreferencesServic
private readonly defaultSettingsRawResource = URI.from({ scheme: network.Schemas.vscode, authority: 'defaultsettings', path: '/defaultSettings.json' });
get userSettingsResource(): URI {
return this.getEditableSettingsURI(ConfigurationTarget.USER)!;
return this.environmentService.settingsResource;
}
get workspaceSettingsResource(): URI | null {
return this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE);
if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
return null;
}
const workspace = this.contextService.getWorkspace();
return workspace.configuration || workspace.folders[0].toResource(FOLDER_SETTINGS_PATH);
}
get settingsEditor2Input(): SettingsEditor2Input {
@@ -103,7 +107,8 @@ export class PreferencesService extends Disposable implements IPreferencesServic
}
getFolderSettingsResource(resource: URI): URI | null {
return this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE_FOLDER, resource);
const folder = this.contextService.getWorkspaceFolder(resource);
return folder ? folder.toResource(FOLDER_SETTINGS_PATH) : null;
}
resolveModel(uri: URI): Promise<ITextModel | null> {
@@ -153,7 +158,7 @@ export class PreferencesService extends Disposable implements IPreferencesServic
return Promise.resolve(null);
}
createPreferencesEditorModel(uri: URI): Promise<IPreferencesEditorModel<any>> {
async createPreferencesEditorModel(uri: URI): Promise<IPreferencesEditorModel<any> | null> {
if (this.isDefaultSettingsResource(uri)) {
return this.createDefaultSettingsEditorModel(uri);
}
@@ -162,16 +167,25 @@ export class PreferencesService extends Disposable implements IPreferencesServic
return this.createEditableSettingsEditorModel(ConfigurationTarget.USER_LOCAL, uri);
}
const workspaceSettingsUri = this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE);
const workspaceSettingsUri = await this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE);
if (workspaceSettingsUri && workspaceSettingsUri.toString() === uri.toString()) {
return this.createEditableSettingsEditorModel(ConfigurationTarget.WORKSPACE, workspaceSettingsUri);
}
if (this.contextService.getWorkbenchState() === WorkbenchState.WORKSPACE) {
return this.createEditableSettingsEditorModel(ConfigurationTarget.WORKSPACE_FOLDER, uri);
const settingsUri = await this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE_FOLDER, uri);
if (settingsUri && settingsUri.toString() === uri.toString()) {
return this.createEditableSettingsEditorModel(ConfigurationTarget.WORKSPACE_FOLDER, uri);
}
}
return Promise.reject(`unknown resource: ${uri.toString()}`);
const remoteEnvironment = await this.remoteAgentService.getEnvironment();
const remoteSettingsUri = remoteEnvironment ? remoteEnvironment.settingsPath : null;
if (remoteSettingsUri && remoteSettingsUri.toString() === uri.toString()) {
return this.createEditableSettingsEditorModel(ConfigurationTarget.USER_REMOTE, uri);
}
return null;
}
openRawDefaultSettings(): Promise<IEditor | null> {
@@ -237,11 +251,11 @@ export class PreferencesService extends Disposable implements IPreferencesServic
this.openOrSwitchSettings2(ConfigurationTarget.WORKSPACE, undefined, options, group);
}
openFolderSettings(folder: URI, jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise<IEditor | null> {
async openFolderSettings(folder: URI, jsonEditor?: boolean, options?: ISettingsEditorOptions, group?: IEditorGroup): Promise<IEditor | null> {
jsonEditor = typeof jsonEditor === 'undefined' ?
this.configurationService.getValue('workbench.settings.editor') === 'json' :
jsonEditor;
const folderSettingsUri = this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE_FOLDER, folder);
const folderSettingsUri = await this.getEditableSettingsURI(ConfigurationTarget.WORKSPACE_FOLDER, folder);
if (jsonEditor) {
if (folderSettingsUri) {
return this.openOrSwitchSettings(ConfigurationTarget.WORKSPACE_FOLDER, folderSettingsUri, options, group);
@@ -389,8 +403,8 @@ export class PreferencesService extends Disposable implements IPreferencesServic
return this.editorService.openEditor(input, SettingsEditorOptions.create(settingsOptions), group);
}
private doSwitchSettings(target: ConfigurationTarget, resource: URI, input: PreferencesEditorInput, group: IEditorGroup, options?: ISettingsEditorOptions): Promise<IEditor> {
const settingsURI = this.getEditableSettingsURI(target, resource);
private async doSwitchSettings(target: ConfigurationTarget, resource: URI, input: PreferencesEditorInput, group: IEditorGroup, options?: ISettingsEditorOptions): Promise<IEditor> {
const settingsURI = await this.getEditableSettingsURI(target, resource);
if (!settingsURI) {
return Promise.reject(`Invalid settings URI - ${resource.toString()}`);
}
@@ -477,18 +491,14 @@ export class PreferencesService extends Disposable implements IPreferencesServic
.then(() => <EditorInput>this.editorService.createInput({ resource }));
}
private createEditableSettingsEditorModel(configurationTarget: ConfigurationTarget, resource: URI): Promise<SettingsEditorModel> {
const settingsUri = this.getEditableSettingsURI(configurationTarget, resource);
if (settingsUri) {
const workspace = this.contextService.getWorkspace();
if (workspace.configuration && workspace.configuration.toString() === settingsUri.toString()) {
return this.textModelResolverService.createModelReference(settingsUri)
.then(reference => this.instantiationService.createInstance(WorkspaceConfigurationEditorModel, reference, configurationTarget));
}
private createEditableSettingsEditorModel(configurationTarget: ConfigurationTarget, settingsUri: URI): Promise<SettingsEditorModel> {
const workspace = this.contextService.getWorkspace();
if (workspace.configuration && workspace.configuration.toString() === settingsUri.toString()) {
return this.textModelResolverService.createModelReference(settingsUri)
.then(reference => this.instantiationService.createInstance(SettingsEditorModel, reference, configurationTarget));
.then(reference => this.instantiationService.createInstance(WorkspaceConfigurationEditorModel, reference, configurationTarget));
}
return Promise.reject(`unknown target: ${configurationTarget} and resource: ${resource.toString()}`);
return this.textModelResolverService.createModelReference(settingsUri)
.then(reference => this.instantiationService.createInstance(SettingsEditorModel, reference, configurationTarget));
}
private createDefaultSettingsEditorModel(defaultSettingsUri: URI): Promise<DefaultSettingsEditorModel> {
@@ -518,23 +528,19 @@ export class PreferencesService extends Disposable implements IPreferencesServic
return this._defaultUserSettingsContentModel;
}
private getEditableSettingsURI(configurationTarget: ConfigurationTarget, resource?: URI): URI | null {
private async getEditableSettingsURI(configurationTarget: ConfigurationTarget, resource?: URI): Promise<URI | null> {
switch (configurationTarget) {
case ConfigurationTarget.USER:
case ConfigurationTarget.USER_LOCAL:
return this.environmentService.settingsResource;
return this.userSettingsResource;
case ConfigurationTarget.USER_REMOTE:
return this.environmentService.settingsResource;
const remoteEnvironment = await this.remoteAgentService.getEnvironment();
return remoteEnvironment ? remoteEnvironment.settingsPath : null;
case ConfigurationTarget.WORKSPACE:
if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
return null;
}
const workspace = this.contextService.getWorkspace();
return workspace.configuration || workspace.folders[0].toResource(FOLDER_SETTINGS_PATH);
return this.workspaceSettingsResource;
case ConfigurationTarget.WORKSPACE_FOLDER:
if (resource) {
const folder = this.contextService.getWorkspaceFolder(resource);
return folder ? folder.toResource(FOLDER_SETTINGS_PATH) : null;
return this.getFolderSettingsResource(resource);
}
}
return null;

View File

@@ -198,7 +198,7 @@ export interface IPreferencesService {
getFolderSettingsResource(resource: URI): URI | null;
resolveModel(uri: URI): Promise<ITextModel | null>;
createPreferencesEditorModel<T>(uri: URI): Promise<IPreferencesEditorModel<T>>;
createPreferencesEditorModel<T>(uri: URI): Promise<IPreferencesEditorModel<T> | null>;
createSettings2EditorModel(): Settings2EditorModel; // TODO
openRawDefaultSettings(): Promise<IEditor | null>;

View File

@@ -375,6 +375,7 @@ function parse(model: ITextModel, isSettingsProperty: (currentProperty: string,
const position = model.getPositionAt(offset);
range.endLineNumber = position.lineNumber;
range.endColumn = position.column;
settingsPropertyIndex = -1;
}
},
onArrayBegin: (offset: number, length: number) => {

View File

@@ -4,18 +4,22 @@
*--------------------------------------------------------------------------------------------*/
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IRemoteAgentConnection } from 'vs/workbench/services/remote/common/remoteAgentService';
import { IRemoteAgentConnection, IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { AbstractRemoteAgentService, RemoteAgentConnection } from 'vs/workbench/services/remote/common/abstractRemoteAgentService';
import { IProductService } from 'vs/platform/product/common/product';
import { browserWebSocketFactory } from 'vs/platform/remote/browser/browserWebSocketFactory';
import { IWebSocketFactory, BrowserSocketFactory } from 'vs/platform/remote/browser/browserSocketFactory';
import { ISignService } from 'vs/platform/sign/common/sign';
import { ISocketFactory } from 'vs/platform/remote/common/remoteAgentConnection';
export class RemoteAgentService extends AbstractRemoteAgentService {
export class RemoteAgentService extends AbstractRemoteAgentService implements IRemoteAgentService {
public readonly socketFactory: ISocketFactory;
private readonly _connection: IRemoteAgentConnection | null = null;
constructor(
webSocketFactory: IWebSocketFactory | null | undefined,
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,
@IProductService productService: IProductService,
@IRemoteAuthorityResolverService remoteAuthorityResolverService: IRemoteAuthorityResolverService,
@@ -23,7 +27,8 @@ export class RemoteAgentService extends AbstractRemoteAgentService {
) {
super(environmentService);
this._connection = this._register(new RemoteAgentConnection(environmentService.configuration.remoteAuthority!, productService.commit, browserWebSocketFactory, environmentService, remoteAuthorityResolverService, signService));
this.socketFactory = new BrowserSocketFactory(webSocketFactory);
this._connection = this._register(new RemoteAgentConnection(environmentService.configuration.remoteAuthority!, productService.commit, this.socketFactory, environmentService, remoteAuthorityResolverService, signService));
}
getConnection(): IRemoteAgentConnection | null {

View File

@@ -8,7 +8,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { IChannel, IServerChannel, getDelayedChannel } from 'vs/base/parts/ipc/common/ipc';
import { Client } from 'vs/base/parts/ipc/common/ipc.net';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { connectRemoteAgentManagement, IConnectionOptions, IWebSocketFactory, PersistenConnectionEvent } from 'vs/platform/remote/common/remoteAgentConnection';
import { connectRemoteAgentManagement, IConnectionOptions, ISocketFactory, PersistenConnectionEvent } from 'vs/platform/remote/common/remoteAgentConnection';
import { IRemoteAgentConnection, IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { IRemoteAuthorityResolverService, RemoteAuthorityResolverError } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
@@ -21,7 +21,7 @@ import { IDiagnosticInfoOptions, IDiagnosticInfo } from 'vs/platform/diagnostics
import { Emitter } from 'vs/base/common/event';
import { ISignService } from 'vs/platform/sign/common/sign';
export abstract class AbstractRemoteAgentService extends Disposable implements IRemoteAgentService {
export abstract class AbstractRemoteAgentService extends Disposable {
_serviceBrand: any;
@@ -83,7 +83,7 @@ export class RemoteAgentConnection extends Disposable implements IRemoteAgentCon
constructor(
remoteAuthority: string,
private readonly _commit: string | undefined,
private readonly _webSocketFactory: IWebSocketFactory,
private readonly _socketFactory: ISocketFactory,
private readonly _environmentService: IEnvironmentService,
private readonly _remoteAuthorityResolverService: IRemoteAuthorityResolverService,
private readonly _signService: ISignService
@@ -113,7 +113,7 @@ export class RemoteAgentConnection extends Disposable implements IRemoteAgentCon
const options: IConnectionOptions = {
isBuilt: this._environmentService.isBuilt,
commit: this._commit,
webSocketFactory: this._webSocketFactory,
socketFactory: this._socketFactory,
addressProvider: {
getAddress: async () => {
if (firstCall) {

View File

@@ -8,7 +8,7 @@ import { RemoteAgentConnectionContext, IRemoteAgentEnvironment } from 'vs/platfo
import { IChannel, IServerChannel } from 'vs/base/parts/ipc/common/ipc';
import { IDiagnosticInfoOptions, IDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnosticsService';
import { Event } from 'vs/base/common/event';
import { PersistenConnectionEvent } from 'vs/platform/remote/common/remoteAgentConnection';
import { PersistenConnectionEvent as PersistentConnectionEvent, ISocketFactory } from 'vs/platform/remote/common/remoteAgentConnection';
export const RemoteExtensionLogFileName = 'remoteagent';
@@ -17,6 +17,8 @@ export const IRemoteAgentService = createDecorator<IRemoteAgentService>('remoteA
export interface IRemoteAgentService {
_serviceBrand: any;
readonly socketFactory: ISocketFactory;
getConnection(): IRemoteAgentConnection | null;
getEnvironment(bail?: boolean): Promise<IRemoteAgentEnvironment | null>;
getDiagnosticInfo(options: IDiagnosticInfoOptions): Promise<IDiagnosticInfo | undefined>;
@@ -27,7 +29,7 @@ export interface IRemoteAgentConnection {
readonly remoteAuthority: string;
readonly onReconnecting: Event<void>;
readonly onDidStateChange: Event<PersistenConnectionEvent>;
readonly onDidStateChange: Event<PersistentConnectionEvent>;
getChannel<T extends IChannel>(channelName: string): T;
registerChannel<T extends IServerChannel<RemoteAgentConnectionContext>>(channelName: string, channel: T): void;

View File

@@ -5,14 +5,17 @@
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IWindowConfiguration } from 'vs/platform/windows/common/windows';
import { IRemoteAgentConnection } from 'vs/workbench/services/remote/common/remoteAgentService';
import { IRemoteAgentConnection, IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver';
import product from 'vs/platform/product/node/product';
import { nodeWebSocketFactory } from 'vs/platform/remote/node/nodeWebSocketFactory';
import { nodeSocketFactory } from 'vs/platform/remote/node/nodeSocketFactory';
import { AbstractRemoteAgentService, RemoteAgentConnection } from 'vs/workbench/services/remote/common/abstractRemoteAgentService';
import { ISignService } from 'vs/platform/sign/common/sign';
import { ISocketFactory } from 'vs/platform/remote/common/remoteAgentConnection';
export class RemoteAgentService extends AbstractRemoteAgentService {
export class RemoteAgentService extends AbstractRemoteAgentService implements IRemoteAgentService {
public readonly socketFactory: ISocketFactory;
private readonly _connection: IRemoteAgentConnection | null = null;
@@ -22,8 +25,9 @@ export class RemoteAgentService extends AbstractRemoteAgentService {
@ISignService signService: ISignService
) {
super(environmentService);
this.socketFactory = nodeSocketFactory;
if (remoteAuthority) {
this._connection = this._register(new RemoteAgentConnection(remoteAuthority, product.commit, nodeWebSocketFactory, environmentService, remoteAuthorityResolverService, signService));
this._connection = this._register(new RemoteAgentConnection(remoteAuthority, product.commit, nodeSocketFactory, environmentService, remoteAuthorityResolverService, signService));
}
}

View File

@@ -12,7 +12,7 @@ import product from 'vs/platform/product/node/product';
import { connectRemoteAgentTunnel, IConnectionOptions } from 'vs/platform/remote/common/remoteAgentConnection';
import { IRemoteAuthorityResolverService } from 'vs/platform/remote/common/remoteAuthorityResolver';
import { ITunnelService, RemoteTunnel } from 'vs/platform/remote/common/tunnel';
import { nodeWebSocketFactory } from 'vs/platform/remote/node/nodeWebSocketFactory';
import { nodeSocketFactory } from 'vs/platform/remote/node/nodeSocketFactory';
import { ISignService } from 'vs/platform/sign/common/sign';
export async function createRemoteTunnel(options: IConnectionOptions, tunnelRemotePort: number): Promise<RemoteTunnel> {
@@ -102,7 +102,7 @@ export class TunnelService implements ITunnelService {
const options: IConnectionOptions = {
isBuilt: this.environmentService.isBuilt,
commit: product.commit,
webSocketFactory: nodeWebSocketFactory,
socketFactory: nodeSocketFactory,
addressProvider: {
getAddress: async () => {
const { authority } = await this.remoteAuthorityResolverService.resolveAuthority(remoteAuthority);

View File

@@ -104,7 +104,7 @@ export class WebTelemetryAppender implements ITelemetryAppender {
this._aiClient.trackEvent('monacoworkbench/' + eventName, data.properties, data.measurements);
}
dispose(): Promise<any> | undefined {
flush(): Promise<any> | undefined {
if (this._aiClient) {
return new Promise(resolve => {
this._aiClient!.flush();

View File

@@ -18,7 +18,8 @@ import { generateTokensCSSForColorMap } from 'vs/editor/common/modes/supports/to
import { IModeService } from 'vs/editor/common/services/modeService';
import { IFileService } from 'vs/platform/files/common/files';
import { ILogService } from 'vs/platform/log/common/log';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { ExtensionMessageCollector } from 'vs/workbench/services/extensions/common/extensionsRegistry';
import { ITMSyntaxExtensionPoint, grammarsExtPoint } from 'vs/workbench/services/textMate/common/TMGrammars';
import { ITextMateService } from 'vs/workbench/services/textMate/common/textMateService';
@@ -50,7 +51,8 @@ export abstract class AbstractTextMateService extends Disposable implements ITex
@IFileService protected readonly _fileService: IFileService,
@INotificationService private readonly _notificationService: INotificationService,
@ILogService private readonly _logService: ILogService,
@IConfigurationService private readonly _configurationService: IConfigurationService
@IConfigurationService private readonly _configurationService: IConfigurationService,
@IStorageService private readonly _storageService: IStorageService
) {
super();
this._styleElement = dom.createStyleSheet();
@@ -219,7 +221,7 @@ export abstract class AbstractTextMateService extends Disposable implements ITex
this._onDidEncounterLanguage.fire(languageId);
}
});
return new TMTokenizationSupport(r.languageId, tokenization, this._notificationService, this._configurationService);
return new TMTokenizationSupport(r.languageId, tokenization, this._notificationService, this._configurationService, this._storageService);
}, e => {
onUnexpectedError(e);
return null;
@@ -328,6 +330,8 @@ export abstract class AbstractTextMateService extends Disposable implements ITex
protected abstract _loadOnigLib(): Promise<IOnigLib> | undefined;
}
const donotAskUpdateKey = 'editor.maxTokenizationLineLength.donotask';
class TMTokenizationSupport implements ITokenizationSupport {
private readonly _languageId: LanguageId;
private readonly _actual: TMTokenization;
@@ -338,11 +342,12 @@ class TMTokenizationSupport implements ITokenizationSupport {
languageId: LanguageId,
actual: TMTokenization,
@INotificationService private readonly _notificationService: INotificationService,
@IConfigurationService private readonly _configurationService: IConfigurationService
@IConfigurationService private readonly _configurationService: IConfigurationService,
@IStorageService private readonly _storageService: IStorageService
) {
this._languageId = languageId;
this._actual = actual;
this._tokenizationWarningAlreadyShown = false;
this._tokenizationWarningAlreadyShown = !!(this._storageService.getBoolean(donotAskUpdateKey, StorageScope.GLOBAL));
this._maxTokenizationLineLength = this._configurationService.getValue<number>('editor.maxTokenizationLineLength');
this._configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration('editor.maxTokenizationLineLength')) {
@@ -368,7 +373,15 @@ class TMTokenizationSupport implements ITokenizationSupport {
if (line.length >= this._maxTokenizationLineLength) {
if (!this._tokenizationWarningAlreadyShown) {
this._tokenizationWarningAlreadyShown = true;
this._notificationService.warn(nls.localize('too many characters', "Tokenization is skipped for long lines for performance reasons. The length of a long line can be configured via `editor.maxTokenizationLineLength`."));
this._notificationService.prompt(
Severity.Warning,
nls.localize('too many characters', "Tokenization is skipped for long lines for performance reasons. The length of a long line can be configured via `editor.maxTokenizationLineLength`."),
[{
label: nls.localize('neverAgain', "Don't Show Again"),
isSecondary: true,
run: () => this._storageService.store(donotAskUpdateKey, true, StorageScope.GLOBAL)
}]
);
}
console.log(`Line (${line.substr(0, 15)}...): longer than ${this._maxTokenizationLineLength} characters, tokenization skipped.`);
return nullTokenize2(this._languageId, line, state, offsetDelta);

View File

@@ -14,6 +14,7 @@ import { ILogService } from 'vs/platform/log/common/log';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IStorageService } from 'vs/platform/storage/common/storage';
export class TextMateService extends AbstractTextMateService {
@@ -23,9 +24,10 @@ export class TextMateService extends AbstractTextMateService {
@IFileService fileService: IFileService,
@INotificationService notificationService: INotificationService,
@ILogService logService: ILogService,
@IConfigurationService configurationService: IConfigurationService
@IConfigurationService configurationService: IConfigurationService,
@IStorageService storageService: IStorageService
) {
super(modeService, themeService, fileService, notificationService, logService, configurationService);
super(modeService, themeService, fileService, notificationService, logService, configurationService, storageService);
}
protected _loadVSCodeTextmate(): Promise<typeof import('vscode-textmate')> {

View File

@@ -20,6 +20,7 @@ import { TextMateWorker } from 'vs/workbench/services/textMate/electron-browser/
import { ITextModel } from 'vs/editor/common/model';
import { Disposable } from 'vs/base/common/lifecycle';
import { UriComponents, URI } from 'vs/base/common/uri';
import { IStorageService } from 'vs/platform/storage/common/storage';
const RUN_TEXTMATE_IN_WORKER = false;
@@ -110,9 +111,10 @@ export class TextMateService extends AbstractTextMateService {
@INotificationService notificationService: INotificationService,
@ILogService logService: ILogService,
@IConfigurationService configurationService: IConfigurationService,
@IStorageService storageService: IStorageService,
@IModelService private readonly _modelService: IModelService,
) {
super(modeService, themeService, fileService, notificationService, logService, configurationService);
super(modeService, themeService, fileService, notificationService, logService, configurationService, storageService);
this._worker = null;
this._workerProxy = null;
this._tokenizers = Object.create(null);