diff --git a/extensions/vscode-api-tests/src/workspace.test.ts b/extensions/vscode-api-tests/src/workspace.test.ts index f083404a722..aff25c2ae4f 100644 --- a/extensions/vscode-api-tests/src/workspace.test.ts +++ b/extensions/vscode-api-tests/src/workspace.test.ts @@ -174,7 +174,29 @@ suite('workspace-namespace', () => { }, err => { // expected }) - }) + }); + + test('registerTextDocumentContentProvider, show virtual document', function() { + + // duplicate registration + let registration = workspace.registerTextDocumentContentProvider('foo', { + open(uri) { + return 'I am virtual'; + }, + close() { + // nothing + } + }); + + return workspace.openTextDocument(Uri.parse('foo://something/path')).then(doc => { + return window.showTextDocument(doc).then(editor => { + + assert.ok(editor.document === doc); + assert.equal(editor.document.getText(), 'I am virtual'); + registration.dispose(); + }) + }); + }); test('findFiles', () => { return workspace.findFiles('*.js', null).then((res) => { diff --git a/src/vs/workbench/api/common/extHostDocuments.ts b/src/vs/workbench/api/common/extHostDocuments.ts index f3e73a5e2b5..2a0e52bb349 100644 --- a/src/vs/workbench/api/common/extHostDocuments.ts +++ b/src/vs/workbench/api/common/extHostDocuments.ts @@ -27,8 +27,10 @@ import {asWinJsPromise} from 'vs/base/common/async'; import {EditorModel, EditorInput} from 'vs/workbench/common/editor'; import {IEditorInput, IResourceInput} from 'vs/platform/editor/common/editor'; import {BaseTextEditorModel} from 'vs/workbench/browser/parts/editor/textEditorModel'; +import {ResourceEditorInput} from 'vs/workbench/browser/parts/editor/resourceEditorInput'; import {IMode} from 'vs/editor/common/modes'; import {IModeService} from 'vs/editor/common/services/modeService'; +import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation'; export interface IModelAddedData { url: URI; @@ -558,8 +560,7 @@ export class ExtHostDocument extends BaseTextDocument { @Remotable.MainContext('MainThreadDocuments') export class MainThreadDocuments { - private _modelService: IModelService; - private _modeService: IModeService; + private _instantiationService: IInstantiationService; private _textFileService: ITextFileService; private _editorService: IWorkbenchEditorService; private _fileService: IFileService; @@ -570,6 +571,7 @@ export class MainThreadDocuments { private _modelIsSynced: {[modelId:string]:boolean;}; constructor( + @IInstantiationService instantiationService: IInstantiationService, @IThreadService threadService: IThreadService, @IModelService modelService: IModelService, @IModeService modeService: IModeService, @@ -579,8 +581,7 @@ export class MainThreadDocuments { @IFileService fileService: IFileService, @IUntitledEditorService untitledEditorService: IUntitledEditorService ) { - this._modelService = modelService; - this._modeService = modeService; + this._instantiationService = instantiationService; this._textFileService = textFileService; this._editorService = editorService; this._fileService = fileService; @@ -695,8 +696,7 @@ export class MainThreadDocuments { default: // create an input that talks back to the extension host - return TPromise.as(new MainThreadExtensionEditorInput(uri, this._proxy, this._modelService, - this._modeService)); + return TPromise.as(this._instantiationService.createInstance(MainThreadExtensionEditorInput, uri, this._proxy)); } } @@ -722,14 +722,19 @@ export class MainThreadDocuments { } } -export class MainThreadExtensionEditorInput extends EditorInput { +export class MainThreadExtensionEditorInput extends ResourceEditorInput { - private _model: MainThreadEditorModel; + private _documents: ExtHostModelService; + private _modeService: IModeService; + private _modelService: IModelService; + private _model: TPromise; - constructor(resource: URI, documents: ExtHostModelService, modelService:IModelService, modeService:IModeService) { - super(); - this._model = new MainThreadEditorModel(resource, documents, modelService, modeService) - // todo@joh name, description + constructor(resource: URI, documents: ExtHostModelService, @IModelService modelService: IModelService, + @IModeService modeService: IModeService, @IInstantiationService instantiationService: IInstantiationService) { + super(resource.fsPath, undefined, resource, modelService, instantiationService); + this._documents = documents; + this._modeService = modeService; + this._modelService = modelService; } getId(): string { @@ -737,8 +742,22 @@ export class MainThreadExtensionEditorInput extends EditorInput { } resolve(refresh?: boolean): TPromise { - // todo@joh proper refresh - return this._model.load(refresh); + + if (!this._model) { + const model = this._modelService.getModel(this.resource); + if (model) { + this._model = TPromise.as(model); + } else { + this._model = this._documents.$openTextDocumentContent(this.resource).then(value => { + const firstLine = value.substr(0, value.search(/\r?\n/) + 1); + return this._modelService.createModel(value, + this._modeService.getOrCreateModeByFilenameOrFirstLine(this.resource.fsPath, firstLine), + this.resource); + }); + } + } + + return this._model.then(() => super.resolve(refresh)); } dispose() { @@ -746,34 +765,3 @@ export class MainThreadExtensionEditorInput extends EditorInput { super.dispose(); } } - -export class MainThreadEditorModel extends BaseTextEditorModel { - - private _resource: URI; - private _documents: ExtHostModelService; - - constructor(resource: URI, documents: ExtHostModelService, @IModelService modelService: IModelService, - @IModeService modeService: IModeService) { - - super(modelService, modeService); - this._documents = documents; - this._resource = resource; - } - - load(refresh?: boolean): TPromise { - return this._documents.$openTextDocumentContent(this._resource).then(value => { - return this.createTextEditorModel(value, this._resource) - }).then(() => { - return this; - }); - } - - protected getOrCreateMode(modeService: IModeService, mime: string, firstLineText?: string): TPromise { - return modeService.getOrCreateModeByFilenameOrFirstLine(this._resource.fsPath, firstLineText); - } - - dispose() { - console.log('MainThreadEditorModel DISPOSE'); - super.dispose(); - } -} \ No newline at end of file