Merge from vscode f2d41726ba5a0e8abfe61b2c743022b1b6372010 (#7415)

* Merge from vscode f2d41726ba5a0e8abfe61b2c743022b1b6372010

* add missing files
This commit is contained in:
Anthony Dresser
2019-09-27 23:30:36 -07:00
committed by GitHub
parent d0fb6de390
commit bca7c8e6bd
123 changed files with 1704 additions and 1330 deletions

View File

@@ -0,0 +1,58 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService';
import { Disposable } from 'vs/base/common/lifecycle';
import { Emitter, Event } from 'vs/base/common/event';
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IAuthTokenService, AuthTokenStatus } from 'vs/platform/auth/common/auth';
export class AuthTokenService extends Disposable implements IAuthTokenService {
_serviceBrand: undefined;
private readonly channel: IChannel;
private _status: AuthTokenStatus = AuthTokenStatus.Disabled;
get status(): AuthTokenStatus { return this._status; }
private _onDidChangeStatus: Emitter<AuthTokenStatus> = this._register(new Emitter<AuthTokenStatus>());
readonly onDidChangeStatus: Event<AuthTokenStatus> = this._onDidChangeStatus.event;
constructor(
@ISharedProcessService sharedProcessService: ISharedProcessService
) {
super();
this.channel = sharedProcessService.getChannel('authToken');
this.channel.call<AuthTokenStatus>('_getInitialStatus').then(status => {
this.updateStatus(status);
this._register(this.channel.listen<AuthTokenStatus>('onDidChangeStatus')(status => this.updateStatus(status)));
});
}
getToken(): Promise<string> {
return this.channel.call('getToken');
}
updateToken(token: string): Promise<void> {
return this.channel.call('updateToken', [token]);
}
refreshToken(): Promise<void> {
return this.channel.call('getToken');
}
deleteToken(): Promise<void> {
return this.channel.call('deleteToken');
}
private async updateStatus(status: AuthTokenStatus): Promise<void> {
this._status = status;
this._onDidChangeStatus.fire(status);
}
}
registerSingleton(IAuthTokenService, AuthTokenService);

View File

@@ -0,0 +1,56 @@
/*---------------------------------------------------------------------------------------------
* 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 { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { URI } from 'vs/base/common/uri';
export class BrowserClipboardService implements IClipboardService {
_serviceBrand: undefined;
private _internalResourcesClipboard: URI[] | undefined;
async writeText(text: string, type?: string): Promise<void> {
if (type) {
return; // TODO@sbatten
}
return navigator.clipboard.writeText(text);
}
async readText(type?: string): Promise<string> {
if (type) {
return ''; // TODO@sbatten
}
return navigator.clipboard.readText();
}
readTextSync(): string | undefined {
return undefined;
}
readFindText(): string {
// @ts-ignore
return undefined;
}
writeFindText(text: string): void { }
writeResources(resources: URI[]): void {
this._internalResourcesClipboard = resources;
}
readResources(): URI[] {
return this._internalResourcesClipboard || [];
}
hasResources(): boolean {
return this._internalResourcesClipboard !== undefined && this._internalResourcesClipboard.length > 0;
}
}
registerSingleton(IClipboardService, BrowserClipboardService, true);

View File

@@ -0,0 +1,80 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { clipboard } from 'electron';
import { URI } from 'vs/base/common/uri';
import { isMacintosh } from 'vs/base/common/platform';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
export class NativeClipboardService implements IClipboardService {
private static FILE_FORMAT = 'code/file-list'; // Clipboard format for files
_serviceBrand: undefined;
async writeText(text: string, type?: 'selection' | 'clipboard'): Promise<void> {
clipboard.writeText(text, type);
}
async readText(type?: 'selection' | 'clipboard'): Promise<string> {
return clipboard.readText(type);
}
readTextSync(): string {
return clipboard.readText();
}
readFindText(): string {
if (isMacintosh) {
return clipboard.readFindText();
}
return '';
}
writeFindText(text: string): void {
if (isMacintosh) {
clipboard.writeFindText(text);
}
}
writeResources(resources: URI[]): void {
if (resources.length) {
clipboard.writeBuffer(NativeClipboardService.FILE_FORMAT, this.resourcesToBuffer(resources));
}
}
readResources(): URI[] {
return this.bufferToResources(clipboard.readBuffer(NativeClipboardService.FILE_FORMAT));
}
hasResources(): boolean {
return clipboard.has(NativeClipboardService.FILE_FORMAT);
}
private resourcesToBuffer(resources: URI[]): Buffer {
return Buffer.from(resources.map(r => r.toString()).join('\n'));
}
private bufferToResources(buffer: Buffer): URI[] {
if (!buffer) {
return [];
}
const bufferValue = buffer.toString();
if (!bufferValue) {
return [];
}
try {
return bufferValue.split('\n').map(f => URI.parse(f));
} catch (error) {
return []; // do not trust clipboard data
}
}
}
registerSingleton(IClipboardService, NativeClipboardService, true);

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ICredentialsService } from 'vs/workbench/services/credentials/common/credentials';
import { ICredentialsService } from 'vs/platform/credentials/common/credentials';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ICredentialsService } from 'vs/workbench/services/credentials/common/credentials';
import { ICredentialsService } from 'vs/platform/credentials/common/credentials';
import { IdleValue } from 'vs/base/common/async';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';

View File

@@ -5,9 +5,9 @@
import { IElectronService } from 'vs/platform/electron/node/electron';
import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService';
import { createChannelSender } from 'vs/base/parts/ipc/node/ipcChannelCreator';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IElectronEnvironmentService } from 'vs/workbench/services/electron/electron-browser/electronEnvironmentService';
import { createChannelSender } from 'vs/base/parts/ipc/node/ipc';
export class ElectronService {

View File

@@ -19,7 +19,6 @@ import { Registry } from 'vs/platform/registry/common/platform';
import { Event } from 'vs/base/common/event';
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
import { IEditorGroupsService, IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IWorkspacesHistoryService } from 'vs/workbench/services/workspace/common/workspacesHistoryService';
import { getCodeEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser';
import { getExcludes, ISearchConfiguration } from 'vs/workbench/services/search/common/search';
import { IExpression } from 'vs/base/common/glob';
@@ -33,6 +32,7 @@ import { coalesce } from 'vs/base/common/arrays';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { withNullAsUndefined } from 'vs/base/common/types';
import { addDisposableListener, EventType, EventHelper } from 'vs/base/browser/dom';
import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
/**
* Stores the selection & view state of an editor and allows to compare it to other selection states.
@@ -138,7 +138,7 @@ export class HistoryService extends Disposable implements IHistoryService {
@IStorageService private readonly storageService: IStorageService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IFileService private readonly fileService: IFileService,
@IWorkspacesHistoryService private readonly workspacesHistoryService: IWorkspacesHistoryService,
@IWorkspacesService private readonly workspacesService: IWorkspacesService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
@IContextKeyService private readonly contextKeyService: IContextKeyService,
@@ -781,7 +781,7 @@ export class HistoryService extends Disposable implements IHistoryService {
const input = arg1 as IResourceInput;
this.workspacesHistoryService.removeFromRecentlyOpened([input.resource]);
this.workspacesService.removeFromRecentlyOpened([input.resource]);
}
private isFileOpened(resource: URI, group: IEditorGroup): boolean {

View File

@@ -15,6 +15,32 @@ import { IFileService } from 'vs/platform/files/common/files';
import { ILabelService } from 'vs/platform/label/common/label';
import { trackFocus } from 'vs/base/browser/dom';
import { Disposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
/**
* A workspace to open in the workbench can either be:
* - a workspace file with 0-N folders (via `workspaceUri`)
* - a single folder (via `folderUri`)
* - empty (via `undefined`)
*/
export type IWorkspace = { workspaceUri: URI } | { folderUri: URI } | undefined;
export interface IWorkspaceProvider {
/**
* The initial workspace to open.
*/
readonly workspace: IWorkspace;
/**
* Asks to open a workspace in the current or a new window.
*
* @param workspace the workspace to open.
* @param options wether to open inside the current window or a new window.
*/
open(workspace: IWorkspace, options?: { reuse?: boolean }): Promise<void>;
}
export class BrowserHostService extends Disposable implements IHostService {
@@ -27,15 +53,27 @@ export class BrowserHostService extends Disposable implements IHostService {
//#endregion
private workspaceProvider: IWorkspaceProvider;
constructor(
@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
@IEditorService private readonly editorService: IEditorService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@IFileService private readonly fileService: IFileService,
@ILabelService private readonly labelService: ILabelService
@ILabelService private readonly labelService: ILabelService,
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService
) {
super();
if (environmentService.options && environmentService.options.workspaceProvider) {
this.workspaceProvider = environmentService.options.workspaceProvider;
} else {
this.workspaceProvider = new class implements IWorkspaceProvider {
readonly workspace = undefined;
async open() { }
};
}
this.registerListeners();
}
@@ -54,33 +92,21 @@ export class BrowserHostService extends Disposable implements IHostService {
readonly windowCount = Promise.resolve(1);
async openInWindow(toOpen: IWindowOpenable[], options?: IOpenInWindowOptions): Promise<void> {
// TODO@Ben delegate to embedder
const { openFolderInNewWindow } = this.shouldOpenNewWindow(options);
for (let i = 0; i < toOpen.length; i++) {
const openable = toOpen[i];
openable.label = openable.label || this.getRecentLabel(openable);
// Folder
if (isFolderToOpen(openable)) {
const newAddress = `${document.location.origin}${document.location.pathname}?folder=${openable.folderUri.path}`;
if (openFolderInNewWindow) {
window.open(newAddress);
} else {
window.location.href = newAddress;
}
this.workspaceProvider.open({ folderUri: openable.folderUri }, { reuse: this.shouldReuse(options) });
}
// Workspace
else if (isWorkspaceToOpen(openable)) {
const newAddress = `${document.location.origin}${document.location.pathname}?workspace=${openable.workspaceUri.path}`;
if (openFolderInNewWindow) {
window.open(newAddress);
} else {
window.location.href = newAddress;
}
this.workspaceProvider.open({ workspaceUri: openable.workspaceUri }, { reuse: this.shouldReuse(options) });
}
// File
// File: open via editor service in current window
else if (isFileToOpen(openable)) {
const inputs: IResourceEditor[] = await pathsToEditors([openable], this.fileService);
this.editorService.openEditors(inputs);
@@ -100,7 +126,7 @@ export class BrowserHostService extends Disposable implements IHostService {
return this.labelService.getUriLabel(openable.fileUri);
}
private shouldOpenNewWindow(options: IOpenInWindowOptions = {}): { openFolderInNewWindow: boolean } {
private shouldReuse(options: IOpenInWindowOptions = {}): boolean {
const windowConfig = this.configurationService.getValue<IWindowSettings>('window');
const openFolderInNewWindowConfig = (windowConfig && windowConfig.openFoldersInNewWindow) || 'default' /* default */;
@@ -109,17 +135,11 @@ export class BrowserHostService extends Disposable implements IHostService {
openFolderInNewWindow = (openFolderInNewWindowConfig === 'on');
}
return { openFolderInNewWindow };
return !openFolderInNewWindow;
}
async openEmptyWindow(options?: IOpenEmptyWindowOptions): Promise<void> {
// TODO@Ben delegate to embedder
const targetHref = `${document.location.origin}${document.location.pathname}?ew=true`;
if (options && options.reuse) {
window.location.href = targetHref;
} else {
window.open(targetHref);
}
this.workspaceProvider.open(undefined, { reuse: options && options.reuse });
}
async toggleFullScreen(): Promise<void> {

View File

@@ -0,0 +1,20 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IIssueService } from 'vs/platform/issue/node/issue';
import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService';
import { createChannelSender } from 'vs/base/parts/ipc/node/ipc';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
export class IssueService {
_serviceBrand: undefined;
constructor(@IMainProcessService mainProcessService: IMainProcessService) {
return createChannelSender<IIssueService>(mainProcessService.getChannel('issue'));
}
}
registerSingleton(IIssueService, IssueService, true);

View File

@@ -0,0 +1,22 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { createChannelSender } from 'vs/base/parts/ipc/node/ipc';
import { ILocalizationsService } from 'vs/platform/localizations/common/localizations';
import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
export class LocalizationsService {
_serviceBrand: undefined;
constructor(
@ISharedProcessService sharedProcessService: ISharedProcessService,
) {
return createChannelSender<ILocalizationsService>(sharedProcessService.getChannel('localizations'));
}
}
registerSingleton(ILocalizationsService, LocalizationsService, true);

View File

@@ -0,0 +1,20 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IMenubarService } from 'vs/platform/menubar/node/menubar';
import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService';
import { createChannelSender } from 'vs/base/parts/ipc/node/ipc';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
export class MenubarService {
_serviceBrand: undefined;
constructor(@IMainProcessService mainProcessService: IMainProcessService) {
return createChannelSender<IMenubarService>(mainProcessService.getChannel('menubar'));
}
}
registerSingleton(IMenubarService, MenubarService, true);

View File

@@ -80,7 +80,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
private contentEncoding: string; // encoding as reported from disk
private preferredEncoding: string; // encoding as chosen by the user
private preferredMode: string; // mode as chosen by the user
private preferredMode: string | undefined; // mode as chosen by the user
private versionId: number;
private bufferSavedVersionId: number;
@@ -108,7 +108,7 @@ export class TextFileEditorModel extends BaseTextEditorModel implements ITextFil
constructor(
resource: URI,
preferredEncoding: string,
preferredMode: string,
preferredMode: string | undefined,
@INotificationService private readonly notificationService: INotificationService,
@IModeService modeService: IModeService,
@IModelService modelService: IModelService,

View File

@@ -24,7 +24,7 @@ export interface IUpdateProvider {
checkForUpdate(): Promise<IUpdate | null>;
}
export class UpdateService extends Disposable implements IUpdateService {
export class BrowserUpdateService extends Disposable implements IUpdateService {
_serviceBrand: undefined;
@@ -92,4 +92,4 @@ export class UpdateService extends Disposable implements IUpdateService {
}
}
registerSingleton(IUpdateService, UpdateService);
registerSingleton(IUpdateService, BrowserUpdateService);

View File

@@ -0,0 +1,61 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
import { Event, Emitter } from 'vs/base/common/event';
import { IUpdateService, State } from 'vs/platform/update/common/update';
import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
export class NativeUpdateService implements IUpdateService {
_serviceBrand: undefined;
private readonly _onStateChange = new Emitter<State>();
readonly onStateChange: Event<State> = this._onStateChange.event;
private _state: State = State.Uninitialized;
get state(): State { return this._state; }
private channel: IChannel;
constructor(@IMainProcessService mainProcessService: IMainProcessService) {
this.channel = mainProcessService.getChannel('update');
// always set this._state as the state changes
this.onStateChange(state => this._state = state);
this.channel.call<State>('_getInitialState').then(state => {
// fire initial state
this._onStateChange.fire(state);
// fire subsequent states as they come in from remote
this.channel.listen<State>('onStateChange')(state => this._onStateChange.fire(state));
});
}
checkForUpdates(context: any): Promise<void> {
return this.channel.call('checkForUpdates', context);
}
downloadUpdate(): Promise<void> {
return this.channel.call('downloadUpdate');
}
applyUpdate(): Promise<void> {
return this.channel.call('applyUpdate');
}
quitAndInstall(): Promise<void> {
return this.channel.call('quitAndInstall');
}
isLatestVersion(): Promise<boolean> {
return this.channel.call('isLatestVersion');
}
}
registerSingleton(IUpdateService, NativeUpdateService);

View File

@@ -6,12 +6,13 @@
import { IURLService, IURLHandler } from 'vs/platform/url/common/url';
import { URI, UriComponents } from 'vs/base/common/uri';
import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService';
import { URLServiceChannelClient, URLHandlerChannel } from 'vs/platform/url/common/urlIpc';
import { URLHandlerChannel } from 'vs/platform/url/common/urlIpc';
import { URLService } from 'vs/platform/url/node/urlService';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import product from 'vs/platform/product/common/product';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IElectronEnvironmentService } from 'vs/workbench/services/electron/electron-browser/electronEnvironmentService';
import { createChannelSender } from 'vs/base/parts/ipc/node/ipc';
export class RelayURLService extends URLService implements IURLHandler {
@@ -24,7 +25,7 @@ export class RelayURLService extends URLService implements IURLHandler {
) {
super();
this.urlService = new URLServiceChannelClient(mainProcessService.getChannel('url'));
this.urlService = createChannelSender(mainProcessService.getChannel('url'));
mainProcessService.registerChannel('urlHandler', new URLHandlerChannel(this));
openerService.registerOpener(this);

View File

@@ -1,31 +0,0 @@
/*---------------------------------------------------------------------------------------------
* 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 { IWorkspacesService, IWorkspaceFolderCreationData, IWorkspaceIdentifier, IEnterWorkspaceResult } from 'vs/platform/workspaces/common/workspaces';
import { URI } from 'vs/base/common/uri';
export class WorkspacesService implements IWorkspacesService {
_serviceBrand: undefined;
enterWorkspace(path: URI): Promise<IEnterWorkspaceResult | undefined> {
throw new Error('Untitled workspaces are currently unsupported in Web');
}
createUntitledWorkspace(folders?: IWorkspaceFolderCreationData[], remoteAuthority?: string): Promise<IWorkspaceIdentifier> {
throw new Error('Untitled workspaces are currently unsupported in Web');
}
deleteUntitledWorkspace(workspace: IWorkspaceIdentifier): Promise<void> {
throw new Error('Untitled workspaces are currently unsupported in Web');
}
getWorkspaceIdentifier(workspacePath: URI): Promise<IWorkspaceIdentifier> {
throw new Error('Untitled workspaces are currently unsupported in Web');
}
}
registerSingleton(IWorkspacesService, WorkspacesService, true);

View File

@@ -1,25 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { Event } from 'vs/base/common/event';
import { URI } from 'vs/base/common/uri';
import { IRecent, IRecentlyOpened } from 'vs/platform/workspaces/common/workspacesHistory';
export const IWorkspacesHistoryService = createDecorator<IWorkspacesHistoryService>('workspacesHistoryService');
export interface IWorkspacesHistoryService {
_serviceBrand: undefined;
readonly onRecentlyOpenedChange: Event<void>;
addRecentlyOpened(recents: IRecent[]): Promise<void>;
removeFromRecentlyOpened(workspaces: URI[]): Promise<void>;
clearRecentlyOpened(): Promise<void>;
getRecentlyOpened(): Promise<IRecentlyOpened>;
}

View File

@@ -1,39 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { URI } from 'vs/base/common/uri';
import { IRecent, IRecentlyOpened } from 'vs/platform/workspaces/common/workspacesHistory';
import { IWorkspacesHistoryService } from 'vs/workbench/services/workspace/common/workspacesHistoryService';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IElectronService } from 'vs/platform/electron/node/electron';
export class NativeWorkspacesHistoryService implements IWorkspacesHistoryService {
_serviceBrand: undefined;
readonly onRecentlyOpenedChange = this.electronService.onRecentlyOpenedChange;
constructor(
@IElectronService private readonly electronService: IElectronService
) { }
async getRecentlyOpened(): Promise<IRecentlyOpened> {
return this.electronService.getRecentlyOpened();
}
async addRecentlyOpened(recents: IRecent[]): Promise<void> {
return this.electronService.addRecentlyOpened(recents);
}
async removeFromRecentlyOpened(paths: URI[]): Promise<void> {
return this.electronService.removeFromRecentlyOpened(paths);
}
async clearRecentlyOpened(): Promise<void> {
return this.electronService.clearRecentlyOpened();
}
}
registerSingleton(IWorkspacesHistoryService, NativeWorkspacesHistoryService, true);

View File

@@ -1,48 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
import { IWorkspacesService, IWorkspaceIdentifier, IWorkspaceFolderCreationData, reviveWorkspaceIdentifier, IEnterWorkspaceResult } from 'vs/platform/workspaces/common/workspaces';
import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService';
import { URI } from 'vs/base/common/uri';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IElectronEnvironmentService } from 'vs/workbench/services/electron/electron-browser/electronEnvironmentService';
export class WorkspacesService implements IWorkspacesService {
_serviceBrand: undefined;
private channel: IChannel;
constructor(
@IMainProcessService mainProcessService: IMainProcessService,
@IElectronEnvironmentService private readonly electronEnvironmentService: IElectronEnvironmentService
) {
this.channel = mainProcessService.getChannel('workspaces');
}
async enterWorkspace(path: URI): Promise<IEnterWorkspaceResult | undefined> {
const result: IEnterWorkspaceResult = await this.channel.call('enterWorkspace', [this.electronEnvironmentService.windowId, path]);
if (result) {
result.workspace = reviveWorkspaceIdentifier(result.workspace);
}
return result;
}
createUntitledWorkspace(folders?: IWorkspaceFolderCreationData[], remoteAuthority?: string): Promise<IWorkspaceIdentifier> {
return this.channel.call('createUntitledWorkspace', [folders, remoteAuthority]).then(reviveWorkspaceIdentifier);
}
deleteUntitledWorkspace(workspaceIdentifier: IWorkspaceIdentifier): Promise<void> {
return this.channel.call('deleteUntitledWorkspace', workspaceIdentifier);
}
getWorkspaceIdentifier(configPath: URI): Promise<IWorkspaceIdentifier> {
return this.channel.call('getWorkspaceIdentifier', configPath).then(reviveWorkspaceIdentifier);
}
}
registerSingleton(IWorkspacesService, WorkspacesService, true);

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
import { IWorkspaceEditingService } from 'vs/workbench/services/workspaces/common/workspaceEditing';
import { URI } from 'vs/base/common/uri';
import * as nls from 'vs/nls';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';

View File

@@ -18,8 +18,8 @@ import { IFileDialogService, IDialogService } from 'vs/platform/dialogs/common/d
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 { AbstractWorkspaceEditingService } from 'vs/workbench/services/workspace/browser/abstractWorkspaceEditingService';
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
import { AbstractWorkspaceEditingService } from 'vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService';
import { IWorkspaceEditingService } from 'vs/workbench/services/workspaces/common/workspaceEditing';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
export class BrowserWorkspaceEditingService extends AbstractWorkspaceEditingService {

View File

@@ -3,18 +3,16 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Event, Emitter } from 'vs/base/common/event';
import { URI } from 'vs/base/common/uri';
import { IRecent, IRecentlyOpened, isRecentFolder, isRecentFile } from 'vs/platform/workspaces/common/workspacesHistory';
import { IWorkspacesHistoryService } from 'vs/workbench/services/workspace/common/workspacesHistoryService';
import { restoreRecentlyOpened, toStoreData } from 'vs/platform/workspaces/common/workspacesHistoryStorage';
import { StorageScope, IStorageService } from 'vs/platform/storage/common/storage';
import { WorkbenchState, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { ILogService } from 'vs/platform/log/common/log';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IWorkspacesService, IWorkspaceFolderCreationData, IWorkspaceIdentifier, IEnterWorkspaceResult, IRecentlyOpened, restoreRecentlyOpened, IRecent, isRecentFile, isRecentFolder, toStoreData } from 'vs/platform/workspaces/common/workspaces';
import { URI } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { ILogService } from 'vs/platform/log/common/log';
import { Disposable } from 'vs/base/common/lifecycle';
export class BrowserWorkspacesHistoryService extends Disposable implements IWorkspacesHistoryService {
export class BrowserWorkspacesService extends Disposable implements IWorkspacesService {
static readonly RECENTLY_OPENED_KEY = 'recently.opened';
@@ -37,7 +35,7 @@ export class BrowserWorkspacesHistoryService extends Disposable implements IWork
private registerListeners(): void {
this._register(this.storageService.onDidChangeStorage(event => {
if (event.key === BrowserWorkspacesHistoryService.RECENTLY_OPENED_KEY && event.scope === StorageScope.GLOBAL) {
if (event.key === BrowserWorkspacesService.RECENTLY_OPENED_KEY && event.scope === StorageScope.GLOBAL) {
this._onRecentlyOpenedChange.fire();
}
}));
@@ -55,8 +53,10 @@ export class BrowserWorkspacesHistoryService extends Disposable implements IWork
}
}
//#region Workspaces History
async getRecentlyOpened(): Promise<IRecentlyOpened> {
const recentlyOpenedRaw = this.storageService.get(BrowserWorkspacesHistoryService.RECENTLY_OPENED_KEY, StorageScope.GLOBAL);
const recentlyOpenedRaw = this.storageService.get(BrowserWorkspacesService.RECENTLY_OPENED_KEY, StorageScope.GLOBAL);
if (recentlyOpenedRaw) {
return restoreRecentlyOpened(JSON.parse(recentlyOpenedRaw), this.logService);
}
@@ -102,12 +102,34 @@ export class BrowserWorkspacesHistoryService extends Disposable implements IWork
}
private async saveRecentlyOpened(data: IRecentlyOpened): Promise<void> {
return this.storageService.store(BrowserWorkspacesHistoryService.RECENTLY_OPENED_KEY, JSON.stringify(toStoreData(data)), StorageScope.GLOBAL);
return this.storageService.store(BrowserWorkspacesService.RECENTLY_OPENED_KEY, JSON.stringify(toStoreData(data)), StorageScope.GLOBAL);
}
async clearRecentlyOpened(): Promise<void> {
this.storageService.remove(BrowserWorkspacesHistoryService.RECENTLY_OPENED_KEY, StorageScope.GLOBAL);
this.storageService.remove(BrowserWorkspacesService.RECENTLY_OPENED_KEY, StorageScope.GLOBAL);
}
//#endregion
//#region Workspace Management
enterWorkspace(path: URI): Promise<IEnterWorkspaceResult | undefined> {
throw new Error('Untitled workspaces are currently unsupported in Web');
}
createUntitledWorkspace(folders?: IWorkspaceFolderCreationData[], remoteAuthority?: string): Promise<IWorkspaceIdentifier> {
throw new Error('Untitled workspaces are currently unsupported in Web');
}
deleteUntitledWorkspace(workspace: IWorkspaceIdentifier): Promise<void> {
throw new Error('Untitled workspaces are currently unsupported in Web');
}
getWorkspaceIdentifier(workspacePath: URI): Promise<IWorkspaceIdentifier> {
throw new Error('Untitled workspaces are currently unsupported in Web');
}
//#endregion
}
registerSingleton(IWorkspacesHistoryService, BrowserWorkspacesHistoryService, true);
registerSingleton(IWorkspacesService, BrowserWorkspacesService, true);

View File

@@ -3,11 +3,10 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common/workspaceEditing';
import { IWorkspaceEditingService } from 'vs/workbench/services/workspaces/common/workspaceEditing';
import { URI } from 'vs/base/common/uri';
import * as nls from 'vs/nls';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IWorkspacesHistoryService } from 'vs/workbench/services/workspace/common/workspacesHistoryService';
import { IJSONEditingService } from 'vs/workbench/services/configuration/common/jsonEditing';
import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
import { WorkspaceService } from 'vs/workbench/services/configuration/browser/configurationService';
@@ -26,7 +25,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ILabelService } from 'vs/platform/label/common/label';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { AbstractWorkspaceEditingService } from 'vs/workbench/services/workspace/browser/abstractWorkspaceEditingService';
import { AbstractWorkspaceEditingService } from 'vs/workbench/services/workspaces/browser/abstractWorkspaceEditingService';
import { IElectronService } from 'vs/platform/electron/node/electron';
import { isMacintosh, isWindows, isLinux } from 'vs/base/common/platform';
import { mnemonicButtonLabel } from 'vs/base/common/labels';
@@ -47,7 +46,6 @@ export class NativeWorkspaceEditingService extends AbstractWorkspaceEditingServi
@ICommandService commandService: ICommandService,
@IFileService fileService: IFileService,
@ITextFileService textFileService: ITextFileService,
@IWorkspacesHistoryService private readonly workspacesHistoryService: IWorkspacesHistoryService,
@IWorkspacesService workspacesService: IWorkspacesService,
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService,
@IFileDialogService fileDialogService: IFileDialogService,
@@ -135,7 +133,7 @@ export class NativeWorkspaceEditingService extends AbstractWorkspaceEditingServi
const newWorkspaceIdentifier = await this.workspacesService.getWorkspaceIdentifier(newWorkspacePath);
const label = this.labelService.getWorkspaceLabel(newWorkspaceIdentifier, { verbose: true });
this.workspacesHistoryService.addRecentlyOpened([{ label, workspace: newWorkspaceIdentifier }]);
this.workspacesService.addRecentlyOpened([{ label, workspace: newWorkspaceIdentifier }]);
this.workspacesService.deleteUntitledWorkspace(workspaceIdentifier);
} catch (error) {

View File

@@ -0,0 +1,24 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
import { IMainProcessService } from 'vs/platform/ipc/electron-browser/mainProcessService';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IElectronEnvironmentService } from 'vs/workbench/services/electron/electron-browser/electronEnvironmentService';
import { createChannelSender } from 'vs/base/parts/ipc/node/ipc';
export class NativeWorkspacesService {
_serviceBrand: undefined;
constructor(
@IMainProcessService mainProcessService: IMainProcessService,
@IElectronEnvironmentService electronEnvironmentService: IElectronEnvironmentService
) {
return createChannelSender<IWorkspacesService>(mainProcessService.getChannel('workspaces'), { context: electronEnvironmentService.windowId });
}
}
registerSingleton(IWorkspacesService, NativeWorkspacesService, true);