more adoption of IWorkspace2

This commit is contained in:
Benjamin Pasero 2017-06-19 10:49:29 +02:00
parent 77bf512f0e
commit f2e1911761
33 changed files with 213 additions and 224 deletions

View file

@ -11,8 +11,7 @@ import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlighte
import { IMatch } from 'vs/base/common/filters';
import uri from 'vs/base/common/uri';
import paths = require('vs/base/common/paths');
import types = require('vs/base/common/types');
import { IWorkspaceProvider, getPathLabel, IUserHomeProvider } from 'vs/base/common/labels';
import { IRootProvider, getPathLabel, IUserHomeProvider } from 'vs/base/common/labels';
export interface IIconLabelCreationOptions {
supportHighlights?: boolean;
@ -99,30 +98,15 @@ export class IconLabel {
export class FileLabel extends IconLabel {
constructor(container: HTMLElement, file: uri, provider: IWorkspaceProvider, userHome?: IUserHomeProvider) {
constructor(container: HTMLElement, file: uri, provider: IRootProvider, userHome?: IUserHomeProvider) {
super(container);
this.setFile(file, provider, userHome);
}
public setFile(file: uri, provider: IWorkspaceProvider, userHome: IUserHomeProvider): void {
const path = getPath(file);
const parent = paths.dirname(path);
public setFile(file: uri, provider: IRootProvider, userHome: IUserHomeProvider): void {
const parent = paths.dirname(file.fsPath);
this.setValue(paths.basename(path), parent && parent !== '.' ? getPathLabel(parent, provider, userHome) : '', { title: path });
this.setValue(paths.basename(file.fsPath), parent && parent !== '.' ? getPathLabel(parent, provider, userHome) : '', { title: file.fsPath });
}
}
function getPath(arg1: uri | IWorkspaceProvider): string {
if (!arg1) {
return null;
}
if (types.isFunction((<IWorkspaceProvider>arg1).getWorkspace)) {
const ws = (<IWorkspaceProvider>arg1).getWorkspace();
return ws ? ws.resource.fsPath : void 0;
}
return (<uri>arg1).fsPath;
}

View file

@ -6,8 +6,7 @@
import URI from 'vs/base/common/uri';
import platform = require('vs/base/common/platform');
import types = require('vs/base/common/types');
import { nativeSep, normalize, isEqualOrParent, isEqual } from 'vs/base/common/paths';
import { nativeSep, normalize, isEqualOrParent, isEqual, basename, join } from 'vs/base/common/paths';
import { endsWith, ltrim } from 'vs/base/common/strings';
export interface ILabelProvider {
@ -18,9 +17,10 @@ export interface ILabelProvider {
getLabel(element: any): string;
}
export interface IWorkspaceProvider {
getWorkspace(): {
resource: URI;
export interface IRootProvider {
getRoot(resource: URI): URI;
getWorkspace2(): {
roots: URI[];
};
}
@ -28,27 +28,42 @@ export interface IUserHomeProvider {
userHome: string;
}
export function getPathLabel(resource: URI | string, basePathProvider?: URI | string | IWorkspaceProvider, userHomeProvider?: IUserHomeProvider): string {
const absolutePath = getPath(resource);
if (!absolutePath) {
export function getPathLabel(resource: URI | string, rootProvider?: IRootProvider, userHomeProvider?: IUserHomeProvider): string {
if (!resource) {
return null;
}
const basepath = basePathProvider && getPath(basePathProvider);
if (typeof resource === 'string') {
resource = URI.file(resource);
}
if (basepath && isEqualOrParent(absolutePath, basepath, !platform.isLinux /* ignorecase */)) {
if (isEqual(basepath, absolutePath, !platform.isLinux /* ignorecase */)) {
return ''; // no label if pathes are identical
// return early if we can resolve a relative path label from the root
const baseResource = rootProvider ? rootProvider.getRoot(resource) : null;
if (baseResource) {
const hasMultipleRoots = rootProvider.getWorkspace2().roots.length > 1;
let pathLabel: string;
if (isEqual(baseResource.fsPath, resource.fsPath, !platform.isLinux /* ignorecase */)) {
pathLabel = ''; // no label if pathes are identical
} else {
pathLabel = normalize(ltrim(resource.fsPath.substr(baseResource.fsPath.length), nativeSep), true);
}
return normalize(ltrim(absolutePath.substr(basepath.length), nativeSep), true);
if (hasMultipleRoots) {
const rootName = basename(baseResource.fsPath);
pathLabel = pathLabel ? join(rootName, pathLabel) : rootName; // always show root basename if there are multiple
}
return pathLabel;
}
if (platform.isWindows && absolutePath && absolutePath[1] === ':') {
return normalize(absolutePath.charAt(0).toUpperCase() + absolutePath.slice(1), true); // convert c:\something => C:\something
// convert c:\something => C:\something
if (platform.isWindows && resource.fsPath && resource.fsPath[1] === ':') {
return normalize(resource.fsPath.charAt(0).toUpperCase() + resource.fsPath.slice(1), true);
}
let res = normalize(absolutePath, true);
// normalize and tildify (macOS, Linux only)
let res = normalize(resource.fsPath, true);
if (!platform.isWindows && userHomeProvider) {
res = tildify(res, userHomeProvider.userHome);
}
@ -56,23 +71,6 @@ export function getPathLabel(resource: URI | string, basePathProvider?: URI | st
return res;
}
function getPath(arg1: URI | string | IWorkspaceProvider): string {
if (!arg1) {
return null;
}
if (typeof arg1 === 'string') {
return arg1;
}
if (types.isFunction((<IWorkspaceProvider>arg1).getWorkspace)) {
const ws = (<IWorkspaceProvider>arg1).getWorkspace();
return ws ? ws.resource.fsPath : void 0;
}
return (<URI>arg1).fsPath;
}
export function tildify(path: string, userHome: string): string {
if (path && (platform.isMacintosh || platform.isLinux) && isEqualOrParent(path, userHome, !platform.isLinux /* ignorecase */)) {
path = `~${path.substr(userHome.length)}`;

View file

@ -10,7 +10,7 @@ import Event, { Emitter } from 'vs/base/common/event';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IExtensionManagementService, DidUninstallExtensionEvent, IExtensionEnablementService } from 'vs/platform/extensionManagement/common/extensionManagement';
import { adoptToGalleryExtensionId, getIdAndVersionFromLocalExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
import { IWorkspaceContextService, ILegacyWorkspace } from 'vs/platform/workspace/common/workspace';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
@ -34,8 +34,8 @@ export class ExtensionEnablementService implements IExtensionEnablementService {
extensionManagementService.onDidUninstallExtension(this.onDidUninstallExtension, this, this.disposables);
}
private get workspace(): ILegacyWorkspace {
return this.contextService.getWorkspace();
private get hasWorkspace(): boolean {
return this.contextService.hasWorkspace();
}
public getGloballyDisabledExtensions(): string[] {
@ -60,7 +60,7 @@ export class ExtensionEnablementService implements IExtensionEnablementService {
}
public setEnablement(identifier: string, enable: boolean, workspace: boolean = false): TPromise<boolean> {
if (workspace && !this.workspace) {
if (workspace && !this.hasWorkspace) {
return TPromise.wrapError<boolean>(localize('noWorkspace', "No workspace."));
}
@ -106,7 +106,7 @@ export class ExtensionEnablementService implements IExtensionEnablementService {
}
private getDisabledExtensions(scope: StorageScope): string[] {
if (scope === StorageScope.WORKSPACE && !this.workspace) {
if (scope === StorageScope.WORKSPACE && !this.hasWorkspace) {
return [];
}
const value = this.storageService.get(DISABLED_EXTENSIONS_STORAGE_PATH, scope, '');

View file

@ -69,7 +69,7 @@ suite('ExtensionEnablementService Test', () => {
test('test when no extensions are disabled for workspace when there is no workspace', (done) => {
testObject.setEnablement('pub.a', false, true)
.then(() => {
instantiationService.stub(IWorkspaceContextService, 'getWorkspace', null);
instantiationService.stub(IWorkspaceContextService, 'hasWorkspace', false);
assert.deepEqual([], testObject.getWorkspaceDisabledExtensions());
})
.then(done, done);
@ -174,7 +174,7 @@ suite('ExtensionEnablementService Test', () => {
});
test('test disable an extension for workspace when there is no workspace throws error', (done) => {
instantiationService.stub(IWorkspaceContextService, 'getWorkspace', null);
instantiationService.stub(IWorkspaceContextService, 'hasWorkspace', false);
testObject.setEnablement('pub.a', false, true)
.then(() => assert.fail('should throw an error'), error => assert.ok(error))
.then(done, done);

View file

@ -8,7 +8,7 @@ import types = require('vs/base/common/types');
import errors = require('vs/base/common/errors');
import strings = require('vs/base/common/strings');
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
import URI from "vs/base/common/uri";
import { IWorkspace } from "vs/platform/workspace/common/workspace";
// Browser localStorage interface
export interface IStorage {
@ -20,11 +20,6 @@ export interface IStorage {
removeItem(key: string): void;
}
export interface IWorkspaceStorageIdentifier {
resource: URI;
uid?: number;
}
export class StorageService implements IStorageService {
public _serviceBrand: any;
@ -43,36 +38,35 @@ export class StorageService implements IStorageService {
constructor(
globalStorage: IStorage,
workspaceStorage: IStorage,
workspaceIdentifier?: IWorkspaceStorageIdentifier
workspace?: IWorkspace,
legacyWorkspaceId?: number
) {
this.globalStorage = globalStorage;
this.workspaceStorage = workspaceStorage || globalStorage;
// Calculate workspace storage key
this.workspaceKey = this.getWorkspaceKey(workspaceIdentifier ? workspaceIdentifier.resource : void 0);
this.workspaceKey = this.getWorkspaceKey(workspace ? workspace.id : void 0);
// Make sure to delete all workspace storage if the workspace has been recreated meanwhile
// which is only possible if a UID property is provided that we can check on
if (workspaceIdentifier && types.isNumber(workspaceIdentifier.uid)) {
this.cleanupWorkspaceScope(workspaceIdentifier.uid);
// which is only possible if a id property is provided that we can check on
if (workspace && types.isNumber(legacyWorkspaceId)) {
this.cleanupWorkspaceScope(legacyWorkspaceId);
}
}
private getWorkspaceKey(workspaceId?: URI): string {
if (!workspaceId) {
private getWorkspaceKey(id?: string): string {
if (!id) {
return StorageService.NO_WORKSPACE_IDENTIFIER;
}
let workspaceIdStr = workspaceId.toString();
// Special case file:// URIs: strip protocol from key to produce shorter key
const fileProtocol = 'file:///';
if (workspaceIdStr.indexOf(fileProtocol) === 0) {
workspaceIdStr = workspaceIdStr.substr(fileProtocol.length);
if (id.indexOf(fileProtocol) === 0) {
id = id.substr(fileProtocol.length);
}
// Always end with "/"
return `${strings.rtrim(workspaceIdStr, '/')}/`;
return `${strings.rtrim(id, '/')}/`;
}
private cleanupWorkspaceScope(workspaceUid: number): void {

View file

@ -8,14 +8,13 @@
import * as assert from 'assert';
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
import { StorageScope } from 'vs/platform/storage/common/storage';
import { IWorkspaceContextService, LegacyWorkspace } from 'vs/platform/workspace/common/workspace';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { StorageService, InMemoryLocalStorage } from 'vs/platform/storage/common/storageService';
import { TestContextService } from 'vs/workbench/test/workbenchTestServices';
import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace';
suite('Workbench StorageSevice', () => {
let contextService, instantiationService;
let contextService: IWorkspaceContextService;
let instantiationService: TestInstantiationService;
setup(() => {
instantiationService = new TestInstantiationService();
@ -23,7 +22,7 @@ suite('Workbench StorageSevice', () => {
});
test('Swap Data with undefined default value', () => {
let s = new StorageService(new InMemoryLocalStorage(), null, contextService.getWorkspace());
let s = new StorageService(new InMemoryLocalStorage(), null, contextService.getWorkspace2());
s.swap('Monaco.IDE.Core.Storage.Test.swap', 'foobar', 'barfoo');
assert.strictEqual('foobar', s.get('Monaco.IDE.Core.Storage.Test.swap'));
@ -34,7 +33,7 @@ suite('Workbench StorageSevice', () => {
});
test('Remove Data', () => {
let s = new StorageService(new InMemoryLocalStorage(), null, contextService.getWorkspace());
let s = new StorageService(new InMemoryLocalStorage(), null, contextService.getWorkspace2());
s.store('Monaco.IDE.Core.Storage.Test.remove', 'foobar');
assert.strictEqual('foobar', s.get('Monaco.IDE.Core.Storage.Test.remove'));
@ -43,7 +42,7 @@ suite('Workbench StorageSevice', () => {
});
test('Get Data, Integer, Boolean', () => {
let s = new StorageService(new InMemoryLocalStorage(), null, contextService.getWorkspace());
let s = new StorageService(new InMemoryLocalStorage(), null, contextService.getWorkspace2());
assert.strictEqual(s.get('Monaco.IDE.Core.Storage.Test.get', StorageScope.GLOBAL, 'foobar'), 'foobar');
assert.strictEqual(s.get('Monaco.IDE.Core.Storage.Test.get', StorageScope.GLOBAL, ''), '');
@ -77,16 +76,15 @@ suite('Workbench StorageSevice', () => {
test('StorageSevice cleans up when workspace changes', () => {
let storageImpl = new InMemoryLocalStorage();
let ws = contextService.getWorkspace();
ws.uid = new Date().getTime();
let s = new StorageService(storageImpl, null, ws);
let time = new Date().getTime();
let s = new StorageService(storageImpl, null, contextService.getWorkspace2(), time);
s.store('key1', 'foobar');
s.store('key2', 'something');
s.store('wkey1', 'foo', StorageScope.WORKSPACE);
s.store('wkey2', 'foo2', StorageScope.WORKSPACE);
s = new StorageService(storageImpl, null, contextService.getWorkspace());
s = new StorageService(storageImpl, null, contextService.getWorkspace2(), time);
assert.strictEqual(s.get('key1', StorageScope.GLOBAL), 'foobar');
assert.strictEqual(s.get('key1', StorageScope.WORKSPACE, null), null);
@ -95,9 +93,7 @@ suite('Workbench StorageSevice', () => {
assert.strictEqual(s.get('wkey1', StorageScope.WORKSPACE), 'foo');
assert.strictEqual(s.get('wkey2', StorageScope.WORKSPACE), 'foo2');
ws = new LegacyWorkspace(TestWorkspace.resource, Date.now());
ws.uid = new Date().getTime() + 100;
s = new StorageService(storageImpl, null, ws);
s = new StorageService(storageImpl, null, contextService.getWorkspace2(), time + 100);
assert.strictEqual(s.get('key1', StorageScope.GLOBAL), 'foobar');
assert.strictEqual(s.get('key1', StorageScope.WORKSPACE, null), null);

View file

@ -10,7 +10,6 @@ import { resolveWorkbenchCommonProperties } from 'vs/platform/telemetry/node/wor
import { StorageService, InMemoryLocalStorage } from 'vs/platform/storage/common/storageService';
import { TestWorkspace } from 'vs/platform/workspace/test/common/testWorkspace';
suite('Telemetry - common properties', function () {
const commit = void 0;

View file

@ -56,7 +56,7 @@ export interface IWindowsService {
getWindowCount(): TPromise<number>;
log(severity: string, ...messages: string[]): TPromise<void>;
// TODO@joao: what?
closeExtensionHostWindow(extensionDevelopmentPath: string): TPromise<void>;
closeExtensionHostWindow(extensionDevelopmentPaths: string[]): TPromise<void>;
showItemInFolder(path: string): TPromise<void>;
// This needs to be handled from browser process to prevent

View file

@ -43,7 +43,7 @@ export interface IWindowsChannel extends IChannel {
call(command: 'whenSharedProcessReady'): TPromise<void>;
call(command: 'toggleSharedProcess'): TPromise<void>;
call(command: 'log', arg: [string, string[]]): TPromise<void>;
call(command: 'closeExtensionHostWindow', arg: string): TPromise<void>;
call(command: 'closeExtensionHostWindow', arg: string[]): TPromise<void>;
call(command: 'showItemInFolder', arg: string): TPromise<void>;
call(command: 'openExternal', arg: string): TPromise<boolean>;
call(command: 'startCrashReporter', arg: Electron.CrashReporterStartOptions): TPromise<void>;
@ -235,8 +235,8 @@ export class WindowsChannelClient implements IWindowsService {
return this.channel.call('log', [severity, messages]);
}
closeExtensionHostWindow(extensionDevelopmentPath: string): TPromise<void> {
return this.channel.call('closeExtensionHostWindow', extensionDevelopmentPath);
closeExtensionHostWindow(extensionDevelopmentPaths: string[]): TPromise<void> {
return this.channel.call('closeExtensionHostWindow', extensionDevelopmentPaths);
}
showItemInFolder(path: string): TPromise<void> {

View file

@ -263,12 +263,12 @@ export class WindowsService implements IWindowsService, IDisposable {
return TPromise.as(null);
}
closeExtensionHostWindow(extensionDevelopmentPath: string): TPromise<void> {
const windowOnExtension = this.windowsMainService.findWindow(null, null, extensionDevelopmentPath);
if (windowOnExtension) {
windowOnExtension.win.close();
}
closeExtensionHostWindow(extensionDevelopmentPaths: string[]): TPromise<void> {
extensionDevelopmentPaths.map(p => this.windowsMainService.findWindow(null, null, p)).forEach(windowOnExtension => {
if (windowOnExtension) {
windowOnExtension.win.close();
}
});
return TPromise.as(null);
}

View file

@ -3,10 +3,12 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { LegacyWorkspace } from 'vs/platform/workspace/common/workspace';
import URI from 'vs/base/common/uri';
import { Workspace } from "vs/platform/workspace/common/workspace";
export const TestWorkspace = new LegacyWorkspace(
URI.file('C:\\testWorkspace'),
Date.now()
const wsUri = URI.file('C:\\testWorkspace');
export const TestWorkspace = new Workspace(
wsUri.toString(),
wsUri.fsPath,
[wsUri]
);

View file

@ -49,13 +49,13 @@ export class MainThreadWorkspace extends MainThreadWorkspaceShape {
// --- search ---
$startSearch(include: string, exclude: string, maxResults: number, requestId: number): Thenable<URI[]> {
const workspace = this._contextService.getWorkspace();
const workspace = this._contextService.getWorkspace2();
if (!workspace) {
return undefined;
}
const search = this._searchService.search({
folderResources: [workspace.resource],
folderResources: workspace.roots,
type: QueryType.File,
maxResults,
includePattern: { [include]: true },

View file

@ -57,6 +57,7 @@ export class ResourceLabel extends IconLabel {
private registerListeners(): void {
this.extensionService.onReady().then(() => this.render(true /* clear cache */)); // update when extensions are loaded with potentially new languages
this.toDispose.push(this.configurationService.onDidUpdateConfiguration(() => this.render(true /* clear cache */))); // update when file.associations change
this.toDispose.push(this.contextService.onDidChangeWorkspaceRoots(() => this.render(true /* clear cache */))); // update when roots change
}
public setLabel(label: IEditorLabel, options?: IResourceLabelOptions): void {

View file

@ -71,7 +71,7 @@ export class TitlebarPart extends Part implements ITitleService {
this.isPure = true;
this.activeEditorListeners = [];
this.workspacePath = contextService.hasWorkspace() ? labels.getPathLabel(contextService.getWorkspace().resource, void 0, environmentService) : '';
this.computeWorkspacePath();
this.init();
@ -100,6 +100,7 @@ export class TitlebarPart extends Part implements ITitleService {
this.toUnbind.push(DOM.addDisposableListener(window, DOM.EventType.FOCUS, () => this.onFocus()));
this.toUnbind.push(this.configurationService.onDidUpdateConfiguration(() => this.onConfigurationChanged(true)));
this.toUnbind.push(this.editorGroupService.onEditorsChanged(() => this.onEditorsChanged()));
this.toUnbind.push(this.contextService.onDidChangeWorkspaceRoots(() => this.onDidChangeWorkspaceRoots()));
}
private onBlur(): void {
@ -112,6 +113,20 @@ export class TitlebarPart extends Part implements ITitleService {
this.updateStyles();
}
private onDidChangeWorkspaceRoots(): void {
this.computeWorkspacePath();
this.setTitle(this.getWindowTitle());
}
private computeWorkspacePath(): void {
const workspace = this.contextService.getWorkspace2();
if (workspace && workspace.roots.length === 1) {
this.workspacePath = labels.getPathLabel(workspace.roots[0], void 0, this.environmentService);
} else {
this.workspacePath = '';
}
}
private onConfigurationChanged(update?: boolean): void {
const currentTitleTemplate = this.titleTemplate;
this.titleTemplate = this.configurationService.lookup<string>('window.title').value;

View file

@ -30,7 +30,7 @@ import { KeyboardMapperFactory } from "vs/workbench/services/keybinding/electron
import { IWindowConfiguration, IPath } from "vs/platform/windows/common/windows";
import { IStorageService } from "vs/platform/storage/common/storage";
import { IEnvironmentService } from "vs/platform/environment/common/environment";
import { StorageService, inMemoryLocalStorageInstance, IWorkspaceStorageIdentifier } from "vs/platform/storage/common/storageService";
import { StorageService, inMemoryLocalStorageInstance } from "vs/platform/storage/common/storageService";
import { webFrame } from 'electron';
@ -97,10 +97,11 @@ function toInputs(paths: IPath[], isUntitledFile?: boolean): IResourceInput[] {
function openWorkbench(configuration: IWindowConfiguration, options: IOptions): TPromise<void> {
return resolveLegacyWorkspace(configuration).then(legacyWorkspace => {
const workspace = legacyWorkspaceToMultiRootWorkspace(legacyWorkspace);
const environmentService = new EnvironmentService(configuration, configuration.execPath);
const workspaceConfigurationService = new WorkspaceConfigurationService(environmentService, legacyWorkspaceToMultiRootWorkspace(legacyWorkspace));
const timerService = new TimerService((<any>window).MonacoEnvironment.timers as IInitData, !!legacyWorkspace);
const storageService = createStorageService(legacyWorkspace, configuration, environmentService);
const workspaceConfigurationService = new WorkspaceConfigurationService(environmentService, workspace);
const timerService = new TimerService((<any>window).MonacoEnvironment.timers as IInitData, !!workspace);
const storageService = createStorageService(legacyWorkspace, workspace, configuration, environmentService);
// Since the configuration service is one of the core services that is used in so many places, we initialize it
// right before startup of the workbench shell to have its data ready for consumers
@ -135,11 +136,15 @@ function openWorkbench(configuration: IWindowConfiguration, options: IOptions):
}
function legacyWorkspaceToMultiRootWorkspace(legacyWorkspace: LegacyWorkspace): Workspace {
return legacyWorkspace ? new Workspace(
if (!legacyWorkspace) {
return null;
}
return new Workspace(
createHash('md5').update(legacyWorkspace.resource.fsPath).update(legacyWorkspace.ctime ? String(legacyWorkspace.ctime) : '').digest('hex'),
path.basename(legacyWorkspace.resource.fsPath),
[legacyWorkspace.resource]
) : null;
);
}
function resolveLegacyWorkspace(configuration: IWindowConfiguration): TPromise<LegacyWorkspace> {
@ -172,10 +177,10 @@ function resolveLegacyWorkspace(configuration: IWindowConfiguration): TPromise<L
});
}
function createStorageService(workspace: LegacyWorkspace, configuration: IWindowConfiguration, environmentService: IEnvironmentService): IStorageService {
let id: IWorkspaceStorageIdentifier;
function createStorageService(legacyWorkspace: LegacyWorkspace, workspace: Workspace, configuration: IWindowConfiguration, environmentService: IEnvironmentService): IStorageService {
let id: string;
if (workspace) {
id = { resource: workspace.resource, uid: workspace.ctime };
id = legacyWorkspace.resource.toString();
} else if (configuration.backupPath) {
// if we do not have a workspace open, we need to find another identifier for the window to store
// workspace UI state. if we have a backup path in the configuration we can use that because this
@ -183,13 +188,13 @@ function createStorageService(workspace: LegacyWorkspace, configuration: IWindow
// dirty files in the workspace.
// We use basename() to produce a short identifier, we do not need the full path. We use a custom
// scheme so that we can later distinguish these identifiers from the workspace one.
id = { resource: uri.from({ path: path.basename(configuration.backupPath), scheme: 'empty' }) };
id = uri.from({ path: path.basename(configuration.backupPath), scheme: 'empty' }).toString();
}
const disableStorage = !!environmentService.extensionTestsPath; // never keep any state when running extension tests!
const storage = disableStorage ? inMemoryLocalStorageInstance : window.localStorage;
return new StorageService(storage, storage, id);
return new StorageService(storage, storage, { id, name: workspace && workspace.name, roots: workspace && workspace.roots }, legacyWorkspace ? legacyWorkspace.ctime : void 0);
}
function loaderError(err: Error): Error {

View file

@ -397,7 +397,7 @@ export class DebugService implements debug.IDebugService {
const process = this.viewModel.focusedProcess;
if (process && session && process.getId() === session.getId() && strings.equalsIgnoreCase(process.configuration.type, 'extensionhost') && this.sessionStates.get(session.getId()) === debug.State.Running &&
process && this.contextService.hasWorkspace() && process.configuration.noDebug) {
this.windowsService.closeExtensionHostWindow(this.contextService.getWorkspace().resource.fsPath);
this.windowsService.closeExtensionHostWindow(this.contextService.getWorkspace2().roots.map(r => r.fsPath));
}
if (session && session.getId() === event.body.sessionId) {
this.onSessionEnd(session);

View file

@ -285,7 +285,7 @@ export abstract class EmmetEditorAction extends EditorAction {
const modeService = accessor.get(IModeService);
const messageService = accessor.get(IMessageService);
const contextService = accessor.get(IWorkspaceContextService);
const workspaceRoot = contextService.getWorkspace() ? contextService.getWorkspace().resource.fsPath : '';
const workspaceRoot = contextService.hasWorkspace() ? contextService.getWorkspace().resource.fsPath : '';
const telemetryService = accessor.get(ITelemetryService);
const commandService = accessor.get(ICommandService);

View file

@ -147,7 +147,7 @@ export class OpenFileHandler extends QuickOpenHandler {
private doFindResults(searchValue: string, cacheKey?: string, maxSortedResults?: number): TPromise<FileQuickOpenModel> {
const query: IQueryOptions = {
folderResources: this.contextService.hasWorkspace() ? [this.contextService.getWorkspace().resource] : [],
folderResources: this.contextService.hasWorkspace() ? this.contextService.getWorkspace2().roots : [],
extraFileResources: getOutOfWorkspaceEditorResources(this.editorGroupService, this.contextService),
filePattern: searchValue,
cacheKey: cacheKey
@ -189,7 +189,7 @@ export class OpenFileHandler extends QuickOpenHandler {
private cacheQuery(cacheKey: string): ISearchQuery {
const options: IQueryOptions = {
folderResources: this.contextService.hasWorkspace() ? [this.contextService.getWorkspace().resource] : [],
folderResources: this.contextService.hasWorkspace() ? this.contextService.getWorkspace2().roots : [],
extraFileResources: getOutOfWorkspaceEditorResources(this.editorGroupService, this.contextService),
filePattern: '',
cacheKey: cacheKey,

View file

@ -28,7 +28,6 @@ import { toResource } from 'vs/workbench/common/editor';
import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IListService } from 'vs/platform/list/browser/listService';
import { explorerItemToFileResource } from 'vs/workbench/parts/files/common/files';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { OS } from 'vs/base/common/platform';
export function isSearchViewletFocussed(viewletService: IViewletService): boolean {
@ -262,7 +261,6 @@ export class FindInFolderAction extends Action {
export const findInFolderCommand = (accessor: ServicesAccessor, resource?: URI) => {
const listService = accessor.get(IListService);
const viewletService = accessor.get(IViewletService);
const contextService = accessor.get(IWorkspaceContextService);
if (!URI.isUri(resource)) {
const focused = listService.getFocused() ? listService.getFocused().getFocus() : void 0;
@ -274,15 +272,9 @@ export const findInFolderCommand = (accessor: ServicesAccessor, resource?: URI)
}
}
if (!URI.isUri(resource) && contextService.hasWorkspace()) {
resource = contextService.getWorkspace().resource;
}
if (URI.isUri(resource)) {
viewletService.openViewlet(Constants.VIEWLET_ID, true).then((viewlet: SearchViewlet) => {
viewlet.searchInFolder(resource);
}).done(null, errors.onUnexpectedError);
}
viewletService.openViewlet(Constants.VIEWLET_ID, true).then((viewlet: SearchViewlet) => {
viewlet.searchInFolder(resource);
}).done(null, errors.onUnexpectedError);
};
export class RefreshAction extends Action {

View file

@ -889,13 +889,9 @@ export class SearchViewlet extends Viewlet {
}
}
public searchInFolder(resource: URI): void {
const workspace = this.contextService.getWorkspace();
if (!workspace) {
return;
}
if (workspace.resource.toString() === resource.toString()) {
public searchInFolder(resource?: URI): void {
const workspaceRelativePath = this.contextService.toWorkspaceRelativePath(resource);
if (!workspaceRelativePath || workspaceRelativePath === '.') {
this.inputPatternIncludes.setValue('');
this.searchWidget.focus();
return;
@ -904,12 +900,10 @@ export class SearchViewlet extends Viewlet {
if (!this.showsFileTypes()) {
this.toggleQueryDetails(true, true);
}
const workspaceRelativePath = this.contextService.toWorkspaceRelativePath(resource);
if (workspaceRelativePath) {
this.inputPatternIncludes.setIsGlobPattern(false);
this.inputPatternIncludes.setValue('./' + workspaceRelativePath);
this.searchWidget.focus(false);
}
this.inputPatternIncludes.setIsGlobPattern(false);
this.inputPatternIncludes.setValue('./' + workspaceRelativePath);
this.searchWidget.focus(false);
}
public onQueryChanged(rerunQuery: boolean, preserveFocus?: boolean): void {
@ -956,7 +950,7 @@ export class SearchViewlet extends Viewlet {
const { expression: includePattern, searchPaths } = this.inputPatternIncludes.getGlob();
const options: IQueryOptions = {
folderResources: this.contextService.hasWorkspace() ? [this.contextService.getWorkspace().resource] : [],
folderResources: this.contextService.hasWorkspace() ? this.contextService.getWorkspace2().roots : [],
extraFileResources: getOutOfWorkspaceEditorResources(this.editorGroupService, this.contextService),
excludePattern,
includePattern,

View file

@ -8,7 +8,7 @@
import * as assert from 'assert';
import { Platform } from 'vs/base/common/platform';
import { TerminalLinkHandler, LineColumnInfo } from 'vs/workbench/parts/terminal/electron-browser/terminalLinkHandler';
import { LegacyWorkspace } from 'vs/platform/workspace/common/workspace';
import { Workspace } from 'vs/platform/workspace/common/workspace';
import { TestContextService } from 'vs/workbench/test/workbenchTestServices';
import URI from 'vs/base/common/uri';
import * as strings from 'vs/base/common/strings';
@ -45,9 +45,9 @@ interface LinkFormatInfo {
column?: string;
}
class TestWorkspace extends LegacyWorkspace {
class TestWorkspace extends Workspace {
constructor(private basePath: string) {
super(new TestURI(basePath));
super(basePath, basePath, [new TestURI(basePath)]);
}
}

View file

@ -227,8 +227,8 @@ class WelcomePage {
recentlyOpened.then(({ folders }) => {
if (this.contextService.hasWorkspace()) {
const current = this.contextService.getWorkspace().resource.fsPath;
folders = folders.filter(folder => !this.pathEquals(folder, current));
const currents = this.contextService.getWorkspace2().roots;
folders = folders.filter(folder => !currents.some(current => this.pathEquals(folder, current.fsPath)));
}
if (!folders.length) {
const recent = container.querySelector('.welcomePage') as HTMLElement;

View file

@ -20,6 +20,7 @@ import { EnvironmentService } from 'vs/platform/environment/node/environmentServ
import { parseArgs } from 'vs/platform/environment/node/argv';
import { RawTextSource } from 'vs/editor/common/model/textSource';
import { TestContextService } from 'vs/workbench/test/workbenchTestServices';
import { Workspace } from "vs/platform/workspace/common/workspace";
class TestEnvironmentService extends EnvironmentService {
@ -48,7 +49,7 @@ const untitledBackupPath = path.join(workspaceBackupPath, 'untitled', crypto.cre
class TestBackupFileService extends BackupFileService {
constructor(workspace: Uri, backupHome: string, workspacesJsonPath: string) {
const fileService = new FileService(workspace.fsPath, { disableWatcher: true }, new TestContextService());
const fileService = new FileService(new TestContextService(new Workspace(workspace.fsPath, workspace.fsPath, [workspace])), { disableWatcher: true });
super(workspaceBackupPath, fileService);
}

View file

@ -124,7 +124,7 @@ suite('ConfigurationEditingService', () => {
instantiationService.stub(ITelemetryService, NullTelemetryService);
instantiationService.stub(IModeService, ModeServiceImpl);
instantiationService.stub(IModelService, instantiationService.createInstance(ModelServiceImpl));
instantiationService.stub(IFileService, instantiationService.createInstance(FileService, workspaceDir, { disableWatcher: true }));
instantiationService.stub(IFileService, new FileService(workspaceService, { disableWatcher: true }));
instantiationService.stub(IUntitledEditorService, instantiationService.createInstance(UntitledEditorService));
instantiationService.stub(ITextFileService, instantiationService.createInstance(TestTextFileService));

View file

@ -19,7 +19,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import nls = require('vs/nls');
import { getPathLabel, IWorkspaceProvider } from 'vs/base/common/labels';
import { getPathLabel } from 'vs/base/common/labels';
import { ResourceMap } from 'vs/base/common/map';
import { once } from 'vs/base/common/event';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
@ -287,7 +287,7 @@ export class WorkbenchEditorService implements IWorkbenchEditorService {
return input;
}
private toDiffLabel(res1: URI, res2: URI, context: IWorkspaceProvider, environment: IEnvironmentService): string {
private toDiffLabel(res1: URI, res2: URI, context: IWorkspaceContextService, environment: IEnvironmentService): string {
const leftName = getPathLabel(res1.fsPath, context, environment);
const rightName = getPathLabel(res2.fsPath, context, environment);

View file

@ -48,7 +48,7 @@ export class FileService implements IFileService {
@IConfigurationService private configurationService: IConfigurationService,
@IWorkspaceContextService private contextService: IWorkspaceContextService,
@IWorkbenchEditorService private editorService: IWorkbenchEditorService,
@IEnvironmentService environmentService: IEnvironmentService,
@IEnvironmentService private environmentService: IEnvironmentService,
@IEditorGroupService private editorGroupService: IEditorGroupService,
@ILifecycleService private lifecycleService: ILifecycleService,
@IMessageService private messageService: IMessageService,
@ -65,13 +65,6 @@ export class FileService implements IFileService {
const configuration = this.configurationService.getConfiguration<IFilesConfiguration>();
// adjust encodings
const encodingOverride: IEncodingOverride[] = [];
encodingOverride.push({ resource: uri.file(environmentService.appSettingsHome), encoding: encoding.UTF8 });
if (this.contextService.hasWorkspace()) {
encodingOverride.push({ resource: uri.file(paths.join(this.contextService.getWorkspace().resource.fsPath, '.vscode')), encoding: encoding.UTF8 });
}
let watcherIgnoredPatterns: string[] = [];
if (configuration.files && configuration.files.watcherExclude) {
watcherIgnoredPatterns = Object.keys(configuration.files.watcherExclude).filter(k => !!configuration.files.watcherExclude[k]);
@ -82,15 +75,14 @@ export class FileService implements IFileService {
errorLogger: (msg: string) => this.onFileServiceError(msg),
encoding: configuration.files && configuration.files.encoding,
autoGuessEncoding: configuration.files && configuration.files.autoGuessEncoding,
encodingOverride,
encodingOverride: this.getEncodingOverrides(),
watcherIgnoredPatterns,
verboseLogging: environmentService.verbose,
useExperimentalFileWatcher: configuration.files.useExperimentalFileWatcher
};
// create service
const workspace = this.contextService.getWorkspace();
this.raw = new NodeFileService(workspace ? workspace.resource.fsPath : void 0, fileServiceConfig, contextService);
this.raw = new NodeFileService(contextService, fileServiceConfig);
// Listeners
this.registerListeners();
@ -140,10 +132,29 @@ export class FileService implements IFileService {
// Editor changing
this.toUnbind.push(this.editorGroupService.onEditorsChanged(() => this.onEditorsChanged()));
// Root changes
this.toUnbind.push(this.contextService.onDidChangeWorkspaceRoots(() => this.onDidChangeWorkspaceRoots()));
// Lifecycle
this.lifecycleService.onShutdown(this.dispose, this);
}
private onDidChangeWorkspaceRoots(): void {
this.updateOptions({ encodingOverride: this.getEncodingOverrides() });
}
private getEncodingOverrides(): IEncodingOverride[] {
const encodingOverride: IEncodingOverride[] = [];
encodingOverride.push({ resource: uri.file(this.environmentService.appSettingsHome), encoding: encoding.UTF8 });
if (this.contextService.hasWorkspace()) {
this.contextService.getWorkspace2().roots.forEach(root => {
encodingOverride.push({ resource: uri.file(paths.join(root.fsPath, '.vscode')), encoding: encoding.UTF8 });
});
}
return encodingOverride;
}
private onEditorsChanged(): void {
this.handleOutOfWorkspaceWatchers();
}
@ -240,11 +251,6 @@ export class FileService implements IFileService {
}
private doMoveItemToTrash(resource: uri): TPromise<void> {
const workspace = this.contextService.getWorkspace();
if (!workspace) {
return TPromise.wrapError<void>('Need a workspace to use this');
}
const absolutePath = resource.fsPath;
const result = shell.moveItemToTrash(absolutePath);
if (!result) {

View file

@ -12,7 +12,6 @@ import crypto = require('crypto');
import assert = require('assert');
import { isParent, FileOperation, FileOperationEvent, IContent, IFileService, IResolveFileOptions, IResolveContentOptions, IFileStat, IStreamContent, IFileOperationResult, FileOperationResult, IUpdateContentOptions, FileChangeType, IImportResult, MAX_FILE_SIZE, FileChangesEvent } from 'vs/platform/files/common/files';
import strings = require('vs/base/common/strings');
import { isEqualOrParent } from 'vs/base/common/paths';
import { ResourceMap } from 'vs/base/common/map';
import arrays = require('vs/base/common/arrays');
@ -80,7 +79,6 @@ export class FileService implements IFileService {
private static FS_REWATCH_DELAY = 300; // delay to rewatch a file that was renamed or deleted (in ms)
private static MAX_DEGREE_OF_PARALLEL_FS_OPS = 10; // degree of parallel fs calls that we accept at the same time
private basePath: string;
private tmpPath: string;
private options: IFileServiceOptions;
@ -94,25 +92,10 @@ export class FileService implements IFileService {
private undeliveredRawFileChangesEvents: IRawFileChange[];
constructor(
basePath: string,
private contextService: IWorkspaceContextService,
options: IFileServiceOptions,
private contextService: IWorkspaceContextService
) {
this.toDispose = [];
this.basePath = basePath ? paths.normalize(basePath) : void 0;
if (this.basePath && this.basePath.indexOf('\\\\') === 0 && strings.endsWith(this.basePath, paths.sep)) {
// for some weird reason, node adds a trailing slash to UNC paths
// we never ever want trailing slashes as our base path unless
// someone opens root ("/").
// See also https://github.com/nodejs/io.js/issues/1765
this.basePath = strings.rtrim(this.basePath, paths.sep);
}
if (this.basePath && !paths.isAbsolute(basePath)) {
throw new Error('basePath has to be an absolute path');
}
this.options = options || Object.create(null);
this.tmpPath = this.options.tmpDir || os.tmpdir();
@ -126,7 +109,7 @@ export class FileService implements IFileService {
this.options.errorLogger = console.error;
}
if (this.basePath && !this.options.disableWatcher) {
if (contextService.hasWorkspace() && !this.options.disableWatcher) {
if (this.options.useExperimentalFileWatcher) {
this.setupNsfwWorkspceWatching();
} else {
@ -158,15 +141,15 @@ export class FileService implements IFileService {
}
private setupWin32WorkspaceWatching(): void {
this.toDispose.push(toDisposable(new WindowsWatcherService(this.basePath, this.options.watcherIgnoredPatterns, e => this._onFileChanges.fire(e), this.options.errorLogger, this.options.verboseLogging).startWatching()));
this.toDispose.push(toDisposable(new WindowsWatcherService(this.contextService, this.options.watcherIgnoredPatterns, e => this._onFileChanges.fire(e), this.options.errorLogger, this.options.verboseLogging).startWatching()));
}
private setupUnixWorkspaceWatching(): void {
this.toDispose.push(toDisposable(new UnixWatcherService(this.basePath, this.options.watcherIgnoredPatterns, e => this._onFileChanges.fire(e), this.options.errorLogger, this.options.verboseLogging).startWatching()));
this.toDispose.push(toDisposable(new UnixWatcherService(this.contextService, this.options.watcherIgnoredPatterns, e => this._onFileChanges.fire(e), this.options.errorLogger, this.options.verboseLogging).startWatching()));
}
private setupNsfwWorkspceWatching(): void {
this.toDispose.push(toDisposable(new NsfwWatcherService(this.basePath, this.options.watcherIgnoredPatterns, e => this._onFileChanges.fire(e), this.options.errorLogger, this.options.verboseLogging, this.contextService).startWatching()));
this.toDispose.push(toDisposable(new NsfwWatcherService(this.contextService, this.options.watcherIgnoredPatterns, e => this._onFileChanges.fire(e), this.options.errorLogger, this.options.verboseLogging).startWatching()));
}
public resolveFile(resource: uri, options?: IResolveFileOptions): TPromise<IFileStat> {

View file

@ -13,6 +13,7 @@ import { toFileChangesEvent, IRawFileChange } from 'vs/workbench/services/files/
import { IWatcherChannel, WatcherChannelClient } from 'vs/workbench/services/files/node/watcher/nsfw/watcherIpc';
import { FileChangesEvent } from 'vs/platform/files/common/files';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { normalize } from "path";
export class FileWatcher {
private static MAX_RESTARTS = 5;
@ -21,12 +22,11 @@ export class FileWatcher {
private restartCounter: number;
constructor(
private basePath: string,
private contextService: IWorkspaceContextService,
private ignored: string[],
private onFileChanges: (changes: FileChangesEvent) => void,
private errorLogger: (msg: string) => void,
private verboseLogging: boolean,
private contextService: IWorkspaceContextService
) {
this.isDisposed = false;
this.restartCounter = 0;
@ -52,7 +52,8 @@ export class FileWatcher {
const service = new WatcherChannelClient(channel);
// Start watching
service.watch({ basePath: this.basePath, ignored: this.ignored, verboseLogging: this.verboseLogging }).then(null, (err) => {
const basePath: string = normalize(this.contextService.getWorkspace2().roots[0].fsPath);
service.watch({ basePath, ignored: this.ignored, verboseLogging: this.verboseLogging }).then(null, (err) => {
if (!(err instanceof Error && err.name === 'Canceled' && err.message === 'Canceled')) {
return TPromise.wrapError(err); // the service lib uses the promise cancel error to indicate the process died, we do not want to bubble this up
}

View file

@ -12,6 +12,8 @@ import uri from 'vs/base/common/uri';
import { toFileChangesEvent, IRawFileChange } from 'vs/workbench/services/files/node/watcher/common';
import { IWatcherChannel, WatcherChannelClient } from 'vs/workbench/services/files/node/watcher/unix/watcherIpc';
import { FileChangesEvent } from 'vs/platform/files/common/files';
import { IWorkspaceContextService } from "vs/platform/workspace/common/workspace";
import { normalize } from "path";
export class FileWatcher {
private static MAX_RESTARTS = 5;
@ -20,7 +22,7 @@ export class FileWatcher {
private restartCounter: number;
constructor(
private basePath: string,
private contextService: IWorkspaceContextService,
private ignored: string[],
private onFileChanges: (changes: FileChangesEvent) => void,
private errorLogger: (msg: string) => void,
@ -50,7 +52,8 @@ export class FileWatcher {
const service = new WatcherChannelClient(channel);
// Start watching
service.watch({ basePath: this.basePath, ignored: this.ignored, verboseLogging: this.verboseLogging }).then(null, (err) => {
const basePath: string = normalize(this.contextService.getWorkspace2().roots[0].fsPath);
service.watch({ basePath: basePath, ignored: this.ignored, verboseLogging: this.verboseLogging }).then(null, (err) => {
if (!(err instanceof Error && err.name === 'Canceled' && err.message === 'Canceled')) {
return TPromise.wrapError(err); // the service lib uses the promise cancel error to indicate the process died, we do not want to bubble this up
}
@ -63,7 +66,6 @@ export class FileWatcher {
if (this.restartCounter <= FileWatcher.MAX_RESTARTS) {
this.errorLogger('[FileWatcher] terminated unexpectedly and is restarted again...');
this.restartCounter++;
// TODO: What do we do for multi-root here?
this.startWatching();
} else {
this.errorLogger('[FileWatcher] failed to start after retrying for some time, giving up. Please report this as a bug report!');

View file

@ -8,11 +8,15 @@
import { IRawFileChange, toFileChangesEvent } from 'vs/workbench/services/files/node/watcher/common';
import { OutOfProcessWin32FolderWatcher } from 'vs/workbench/services/files/node/watcher/win32/csharpWatcherService';
import { FileChangesEvent } from 'vs/platform/files/common/files';
import { IWorkspaceContextService } from "vs/platform/workspace/common/workspace";
import { normalize } from "path";
import { rtrim, endsWith } from "vs/base/common/strings";
import { sep } from "vs/base/common/paths";
export class FileWatcher {
constructor(
private basePath: string,
private contextService: IWorkspaceContextService,
private ignored: string[],
private onFileChanges: (changes: FileChangesEvent) => void,
private errorLogger: (msg: string) => void,
@ -21,8 +25,18 @@ export class FileWatcher {
}
public startWatching(): () => void {
let watcher = new OutOfProcessWin32FolderWatcher(
this.basePath,
let basePath: string = normalize(this.contextService.getWorkspace2().roots[0].fsPath);
if (basePath && basePath.indexOf('\\\\') === 0 && endsWith(basePath, sep)) {
// for some weird reason, node adds a trailing slash to UNC paths
// we never ever want trailing slashes as our base path unless
// someone opens root ("/").
// See also https://github.com/nodejs/io.js/issues/1765
basePath = rtrim(basePath, sep);
}
const watcher = new OutOfProcessWin32FolderWatcher(
basePath,
this.ignored,
(events) => this.onRawFileEvents(events),
(error) => this.onError(error),

View file

@ -20,6 +20,7 @@ import encodingLib = require('vs/base/node/encoding');
import utils = require('vs/workbench/services/files/test/node/utils');
import { onError } from 'vs/base/test/common/utils';
import { TestContextService } from "vs/workbench/test/workbenchTestServices";
import { Workspace } from "vs/platform/workspace/common/workspace";
suite('FileService', () => {
let service: FileService;
@ -36,7 +37,7 @@ suite('FileService', () => {
return onError(error, done);
}
service = new FileService(testDir, { disableWatcher: true }, new TestContextService());
service = new FileService(new TestContextService(new Workspace(testDir, testDir, [uri.file(testDir)])), { disableWatcher: true });
done();
});
});
@ -732,11 +733,11 @@ suite('FileService', () => {
encoding: 'utf16le'
});
let _service = new FileService(_testDir, {
let _service = new FileService(new TestContextService(new Workspace(_testDir, _testDir, [uri.file(_testDir)])), {
encoding: 'windows1252',
encodingOverride: encodingOverride,
encodingOverride,
disableWatcher: true
}, new TestContextService());
});
_service.resolveContent(uri.file(path.join(testDir, 'index.html'))).done(c => {
assert.equal(c.encoding, 'windows1252');
@ -760,9 +761,9 @@ suite('FileService', () => {
let _sourceDir = require.toUrl('./fixtures/service');
let resource = uri.file(path.join(testDir, 'index.html'));
let _service = new FileService(_testDir, {
let _service = new FileService(new TestContextService(new Workspace(_testDir, _testDir, [uri.file(_testDir)])), {
disableWatcher: true
}, new TestContextService());
});
extfs.copy(_sourceDir, _testDir, () => {
fs.readFile(resource.fsPath, (error, data) => {

View file

@ -9,6 +9,7 @@ import assert = require('assert');
import os = require('os');
import path = require('path');
import fs = require('fs');
import uri from 'vs/base/common/uri';
import * as json from 'vs/base/common/json';
import { OS } from 'vs/base/common/platform';
import { USLayoutResolvedKeybinding } from 'vs/platform/keybinding/common/usLayoutResolvedKeybinding';
@ -17,7 +18,7 @@ import { KeyCode, SimpleKeybinding, ChordKeybinding } from 'vs/base/common/keyCo
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import extfs = require('vs/base/node/extfs');
import { TestTextFileService, TestEditorGroupService, TestLifecycleService, TestBackupFileService, TestContextService } from 'vs/workbench/test/workbenchTestServices';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IWorkspaceContextService, Workspace } from 'vs/platform/workspace/common/workspace';
import uuid = require('vs/base/common/uuid');
import { ConfigurationService } from 'vs/platform/configuration/node/configurationService';
import { FileService } from 'vs/workbench/services/files/node/fileService';
@ -53,7 +54,7 @@ suite('Keybindings Editing', () => {
let instantiationService: TestInstantiationService;
let testObject: KeybindingsEditingService;
let testDir;
let testDir: string;
let keybindingsFile;
setup(() => {
@ -73,7 +74,7 @@ suite('Keybindings Editing', () => {
instantiationService.stub(ITelemetryService, NullTelemetryService);
instantiationService.stub(IModeService, ModeServiceImpl);
instantiationService.stub(IModelService, instantiationService.createInstance(ModelServiceImpl));
instantiationService.stub(IFileService, new FileService(testDir, { disableWatcher: true }, new TestContextService()));
instantiationService.stub(IFileService, new FileService(new TestContextService(new Workspace(testDir, testDir, [uri.file(testDir)])), { disableWatcher: true }));
instantiationService.stub(IUntitledEditorService, instantiationService.createInstance(UntitledEditorService));
instantiationService.stub(ITextFileService, instantiationService.createInstance(TestTextFileService));
instantiationService.stub(ITextModelService, <ITextModelService>instantiationService.createInstance(TextModelResolverService));

View file

@ -64,7 +64,7 @@ export const TestEnvironmentService = new EnvironmentService(parseArgs(process.a
export class TestContextService implements IWorkspaceContextService {
public _serviceBrand: any;
private workspace: ILegacyWorkspace;
private workspace: IWorkspace;
private id: string;
private options: any;
@ -82,7 +82,7 @@ export class TestContextService implements IWorkspaceContextService {
}
public getFolders(): URI[] {
return this.workspace ? [this.workspace.resource] : [];
return this.workspace ? this.workspace.roots : [];
}
public hasWorkspace(): boolean {
@ -90,15 +90,15 @@ export class TestContextService implements IWorkspaceContextService {
}
public getWorkspace(): ILegacyWorkspace {
return this.workspace;
return this.workspace ? { resource: this.workspace.roots[0] } : void 0;
}
public getWorkspace2(): IWorkspace {
return this.workspace ? { id: this.id, roots: [this.workspace.resource], name: this.workspace.resource.fsPath } : void 0;
return this.workspace;
}
public getRoot(resource: URI): URI {
return this.isInsideWorkspace(resource) ? this.workspace.resource : null;
return this.isInsideWorkspace(resource) ? this.workspace.roots[0] : null;
}
public setWorkspace(workspace: any): void {
@ -115,7 +115,7 @@ export class TestContextService implements IWorkspaceContextService {
public isInsideWorkspace(resource: URI): boolean {
if (resource && this.workspace) {
return paths.isEqualOrParent(resource.fsPath, this.workspace.resource.fsPath, !isLinux /* ignorecase */);
return paths.isEqualOrParent(resource.fsPath, this.workspace.roots[0].fsPath, !isLinux /* ignorecase */);
}
return false;
@ -363,7 +363,7 @@ export class TestStorageService extends EventEmitter implements IStorageService
super();
let context = new TestContextService();
this.storage = new StorageService(new InMemoryLocalStorage(), null, context.getWorkspace());
this.storage = new StorageService(new InMemoryLocalStorage(), null, context.getWorkspace2());
}
store(key: string, value: any, scope: StorageScope = StorageScope.GLOBAL): void {
@ -1012,7 +1012,7 @@ export class TestWindowsService implements IWindowsService {
return TPromise.as(void 0);
}
// TODO@joao: what?
closeExtensionHostWindow(extensionDevelopmentPath: string): TPromise<void> {
closeExtensionHostWindow(extensionDevelopmentPaths: string[]): TPromise<void> {
return TPromise.as(void 0);
}
showItemInFolder(path: string): TPromise<void> {