diff --git a/extensions/vscode-api-tests/src/workspace.test.ts b/extensions/vscode-api-tests/src/workspace.test.ts index 56274efbca5..ec62e5fb21a 100644 --- a/extensions/vscode-api-tests/src/workspace.test.ts +++ b/extensions/vscode-api-tests/src/workspace.test.ts @@ -6,7 +6,7 @@ 'use strict'; import * as assert from 'assert'; -import {workspace, TextDocument, window, Position, Uri, CancellationTokenSource, Disposable} from 'vscode'; +import {workspace, TextDocument, window, Position, Uri, EventEmitter, CancellationTokenSource, Disposable} from 'vscode'; import {createRandomFile, deleteFile, cleanUp, pathEquals} from './utils'; import {join, basename} from 'path'; import * as fs from 'fs'; @@ -286,26 +286,16 @@ suite('workspace-namespace', () => { test('registerTextDocumentContentProvider, change event', function() { let callCount = 0; - let listeners: Function[] = []; + let emitter = new EventEmitter(); + let registration = workspace.registerTextDocumentContentProvider('foo', { - onDidChange(callback, thisArg, disposables) { - let actual = thisArg ? callback.bind(thisArg) : callback; - listeners.push(actual); - let subscription = new Disposable(() => { - const idx = listeners.indexOf(actual); - listeners.splice(idx, 1); - }); - if (Array.isArray(disposables)) { - disposables.push(subscription); - } - return subscription; - }, + onDidChange: emitter.event, provideTextDocumentContent(uri) { return 'call' + (callCount++); } }); - const uri = Uri.parse('foo://testing/path2'); + const uri = Uri.parse('foo://testing/path3'); return workspace.openTextDocument(uri).then(doc => { @@ -320,7 +310,7 @@ suite('workspace-namespace', () => { resolve(); }); - listeners.forEach(l => l(doc.uri)); + emitter.fire(doc.uri); registration.dispose(); }); diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index e6efc70fb87..fd4925fb748 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -999,6 +999,35 @@ declare namespace vscode { (listener: (e: T) => any, thisArgs?: any, disposables?: Disposable[]): Disposable; } + /** + * An event emitter can be used to create and manage an [event](#Event) for others + * to subscribe to. One emitter always owns one event. + * + * Use this class if you want to provide event from within your extension, for instance + * inside a [TextDocumentContentProvider](#TextDocumentContentProvider)mor when providing + * API to other extensions. + */ + export class EventEmitter { + + /** + * The event listeners can subscribe to. + */ + event: Event; + + /** + * Notify all subscribers of the [event](EventEmitter#event). Failure + * of one or more listener will not fail this function call. + * + * @param data The event object. + */ + fire(data?: T): void; + + /** + * Dispose this object and free resources. + */ + dispose(): void; + } + /** * A file system watcher notifies about changes to files and folders * on disk. diff --git a/src/vs/workbench/api/node/extHost.api.impl.ts b/src/vs/workbench/api/node/extHost.api.impl.ts index 1573a9b491a..a3b037dc6b0 100644 --- a/src/vs/workbench/api/node/extHost.api.impl.ts +++ b/src/vs/workbench/api/node/extHost.api.impl.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; +import {Emitter} from 'vs/base/common/event'; import {IBracketElectricCharacterContribution} from 'vs/editor/common/modes/supports'; import {score} from 'vs/editor/common/modes/languageSelector'; import {Remotable, IThreadService} from 'vs/platform/thread/common/thread'; @@ -71,6 +72,7 @@ export class ExtHostAPIImplementation { Range: typeof vscode.Range; Selection: typeof vscode.Selection; CancellationTokenSource: typeof vscode.CancellationTokenSource; + EventEmitter: typeof vscode.EventEmitter; Hover: typeof vscode.Hover; DocumentHighlightKind: typeof vscode.DocumentHighlightKind; DocumentHighlight: typeof vscode.DocumentHighlight; @@ -106,7 +108,8 @@ export class ExtHostAPIImplementation { this.Uri = URI; this.Location = extHostTypes.Location; this.Diagnostic = extHostTypes.Diagnostic; - this.DiagnosticSeverity = extHostTypes.DiagnosticSeverity; + this.DiagnosticSeverity = extHostTypes.DiagnosticSeverity; + this.EventEmitter = Emitter; this.Disposable = extHostTypes.Disposable; this.TextEdit = extHostTypes.TextEdit; this.WorkspaceEdit = extHostTypes.WorkspaceEdit;