From f345c94847db9bae3acea651ba3a60b309374e90 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Tue, 12 Jan 2016 10:50:45 +0100 Subject: [PATCH] virtual doc - support content provider signalling change via onDidChange event --- .../vscode-api-tests/src/workspace.test.ts | 49 +++++++++++++++++-- src/vs/workbench/api/node/extHostDocuments.ts | 28 ++++++++++- 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/extensions/vscode-api-tests/src/workspace.test.ts b/extensions/vscode-api-tests/src/workspace.test.ts index 92f5d43fcf8..6370b4117bb 100644 --- a/extensions/vscode-api-tests/src/workspace.test.ts +++ b/extensions/vscode-api-tests/src/workspace.test.ts @@ -6,11 +6,10 @@ 'use strict'; import * as assert from 'assert'; -import {workspace, TextDocument, window, Position, Uri, CancellationTokenSource} from 'vscode'; +import {workspace, TextDocument, window, Position, Uri, CancellationTokenSource, Disposable} from 'vscode'; import {createRandomFile, deleteFile, cleanUp, pathEquals} from './utils'; import {join, basename} from 'path'; import * as fs from 'fs'; -import * as os from 'os'; suite('workspace-namespace', () => { @@ -209,6 +208,50 @@ suite('workspace-namespace', () => { }); }); + test('registerTextDocumentContentProvider, change event', function() { + + let callCount = 0; + let listeners: Function[] = []; + 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; + }, + provideTextDocumentContent(uri) { + return 'call' + (callCount++); + } + }); + + const uri = Uri.parse('foo://testing/path2'); + + return workspace.openTextDocument(uri).then(doc => { + + assert.equal(callCount, 1); + assert.equal(doc.getText(), 'call0'); + + return new Promise((resolve, reject) => { + + workspace.onDidChangeTextDocument(event => { + assert.ok(event.document === doc); + assert.equal(event.document.getText(), 'call1'); + resolve(); + }); + + listeners.forEach(l => l(doc.uri)); + + registration.dispose(); + }); + }); + }); + test('findFiles', () => { return workspace.findFiles('*.js', null).then((res) => { assert.equal(res.length, 1); @@ -226,4 +269,4 @@ suite('workspace-namespace', () => { assert.equal(res, void 0); }); }); -}); \ No newline at end of file +}); diff --git a/src/vs/workbench/api/node/extHostDocuments.ts b/src/vs/workbench/api/node/extHostDocuments.ts index b5f6b478ec4..ce453bb14ee 100644 --- a/src/vs/workbench/api/node/extHostDocuments.ts +++ b/src/vs/workbench/api/node/extHostDocuments.ts @@ -134,7 +134,23 @@ export class ExtHostModelService { throw new Error(`scheme '${scheme}' already registered`); } this._documentContentProviders[scheme] = provider; - return new Disposable(() => delete this._documentContentProviders[scheme]); + + let subscription: IDisposable; + if (typeof provider.onDidChange === 'function') { + subscription = provider.onDidChange(uri => { + if (this._documentData[uri.toString()]) { + this.$provideTextDocumentContent(uri).then(value => { + return this._proxy.$onVirtualDocumentChange(uri, value); + }, onUnexpectedError); + } + }); + } + return new Disposable(() => { + delete this._documentContentProviders[scheme]; + if (subscription) { + subscription.dispose(); + } + }); } $provideTextDocumentContent(uri: URI): TPromise { @@ -599,6 +615,8 @@ export class MainThreadDocuments { }); } + // --- virtual document logic + private _handleAnyScheme(uri: URI): TPromise { if (this._modelService.getModel(uri)) { @@ -633,4 +651,12 @@ export class MainThreadDocuments { return true; }); } + + $onVirtualDocumentChange(uri: URI, value: string): TPromise { + const model = this._modelService.getModel(uri); + if (model) { + model.setValue(value); + return; + } + } } -- GitLab