/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 'use strict'; import { Emitter, Event } from 'vs/base/common/event'; import { IRelativePattern, parse } from 'vs/base/common/glob'; import URI, { UriComponents } from 'vs/base/common/uri'; import * as vscode from 'vscode'; import { ExtHostFileSystemEventServiceShape, FileSystemEvents } from './extHost.protocol'; import { Disposable } from './extHostTypes'; import { TPromise } from 'vs/base/common/winjs.base'; class FileSystemWatcher implements vscode.FileSystemWatcher { private _onDidCreate = new Emitter(); private _onDidChange = new Emitter(); private _onDidDelete = new Emitter(); private _disposable: Disposable; private _config: number; get ignoreCreateEvents(): boolean { return Boolean(this._config & 0b001); } get ignoreChangeEvents(): boolean { return Boolean(this._config & 0b010); } get ignoreDeleteEvents(): boolean { return Boolean(this._config & 0b100); } constructor(dispatcher: Event, globPattern: string | IRelativePattern, ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean) { this._config = 0; if (ignoreCreateEvents) { this._config += 0b001; } if (ignoreChangeEvents) { this._config += 0b010; } if (ignoreDeleteEvents) { this._config += 0b100; } const parsedPattern = parse(globPattern); let subscription = dispatcher(events => { if (!ignoreCreateEvents) { for (let created of events.created) { let uri = URI.revive(created); if (parsedPattern(uri.fsPath)) { this._onDidCreate.fire(uri); } } } if (!ignoreChangeEvents) { for (let changed of events.changed) { let uri = URI.revive(changed); if (parsedPattern(uri.fsPath)) { this._onDidChange.fire(uri); } } } if (!ignoreDeleteEvents) { for (let deleted of events.deleted) { let uri = URI.revive(deleted); if (parsedPattern(uri.fsPath)) { this._onDidDelete.fire(uri); } } } }); this._disposable = Disposable.from(this._onDidCreate, this._onDidChange, this._onDidDelete, subscription); } dispose() { this._disposable.dispose(); } get onDidCreate(): Event { return this._onDidCreate.event; } get onDidChange(): Event { return this._onDidChange.event; } get onDidDelete(): Event { return this._onDidDelete.event; } } export class ExtHostFileSystemEventService implements ExtHostFileSystemEventServiceShape { private _onFileEvent = new Emitter(); private _onDidRenameFile = new Emitter(); private _onWillRenameFile = new Emitter(); readonly onDidRenameFile: Event = this._onDidRenameFile.event; readonly onWillRenameFile: Event = this._onWillRenameFile.event; constructor() { } public createFileSystemWatcher(globPattern: string | IRelativePattern, ignoreCreateEvents?: boolean, ignoreChangeEvents?: boolean, ignoreDeleteEvents?: boolean): vscode.FileSystemWatcher { return new FileSystemWatcher(this._onFileEvent.event, globPattern, ignoreCreateEvents, ignoreChangeEvents, ignoreDeleteEvents); } $onFileEvent(events: FileSystemEvents) { this._onFileEvent.fire(events); } $onFileRename(oldUri: UriComponents, newUri: UriComponents) { this._onDidRenameFile.fire(Object.freeze({ oldUri: URI.revive(oldUri), newUri: URI.revive(newUri) })); } $onWillRename(oldUri: UriComponents, newUri: UriComponents): TPromise { let thenables: Thenable[] = []; this._onWillRenameFile.fire({ oldUri: URI.revive(oldUri), newUri: URI.revive(newUri), waitUntil(thenable: Thenable): void { if (Object.isFrozen(thenables)) { throw new Error('waitUntil cannot be called async'); } thenables.push(thenable.then(undefined, err => console.error(err))); } }); Object.freeze(thenables); return TPromise.join(thenables); } }