notebook.contribution.ts 7.8 KB
Newer Older
P
Peng Lyu 已提交
1 2 3 4 5
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

R
rebornix 已提交
6 7
import * as nls from 'vs/nls';
import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry';
8
import { IEditorOptions, ITextEditorOptions } from 'vs/platform/editor/common/editor';
P
Peng Lyu 已提交
9
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
10 11 12
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
P
Peng Lyu 已提交
13 14
import { Registry } from 'vs/platform/registry/common/platform';
import { EditorDescriptor, Extensions as EditorExtensions, IEditorRegistry } from 'vs/workbench/browser/editor';
15
import { Extensions as WorkbenchExtensions, IWorkbenchContribution, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
16
import { IEditorInput, IEditorInputFactoryRegistry, Extensions as EditorInputExtensions, IEditorInputFactory, EditorInput } from 'vs/workbench/common/editor';
17 18
import { NotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookEditor';
import { NotebookEditorInput } from 'vs/workbench/contrib/notebook/browser/notebookEditorInput';
19
import { INotebookService, NotebookService, parseCellUri } from 'vs/workbench/contrib/notebook/browser/notebookService';
20 21
import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService';
import { IEditorService, IOpenEditorOverride } from 'vs/workbench/services/editor/common/editorService';
22 23 24 25 26 27
import { ITextModelContentProvider, ITextModelService } from 'vs/editor/common/services/resolverService';
import { ITextModel } from 'vs/editor/common/model';
import { URI } from 'vs/base/common/uri';
import { IModelService } from 'vs/editor/common/services/modelService';
import { IModeService } from 'vs/editor/common/services/modeService';
import { IDisposable } from 'vs/base/common/lifecycle';
28 29
import { assertType } from 'vs/base/common/types';
import { parse } from 'vs/base/common/marshalling';
R
rebornix 已提交
30 31 32 33 34 35 36

// Output renderers registration

import 'vs/workbench/contrib/notebook/browser/output/transforms/streamTransform';
import 'vs/workbench/contrib/notebook/browser/output/transforms/errorTransform';
import 'vs/workbench/contrib/notebook/browser/output/transforms/richTransform';

37 38
// Actions
import 'vs/workbench/contrib/notebook/browser/notebookActions';
P
Peng Lyu 已提交
39 40 41 42 43 44 45 46 47 48 49 50

Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerEditor(
	EditorDescriptor.create(
		NotebookEditor,
		NotebookEditor.ID,
		'Notebook Editor'
	),
	[
		new SyncDescriptor(NotebookEditorInput)
	]
);

51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
Registry.as<IEditorInputFactoryRegistry>(EditorInputExtensions.EditorInputFactories).registerEditorInputFactory(
	NotebookEditorInput.ID,
	class implements IEditorInputFactory {
		canSerialize(): boolean {
			return true;
		}
		serialize(input: EditorInput): string {
			assertType(input instanceof NotebookEditorInput);
			return JSON.stringify({
				resource: input.resource,
				name: input.name,
				viewType: input.viewType,
			});
		}
		deserialize(instantiationService: IInstantiationService, raw: string) {
			type Data = { resource: URI, name: string, viewType: string };
			const data = <Data>parse(raw);
			if (!data) {
				return undefined;
			}
			const { resource, name, viewType } = data;
			if (!data || !URI.isUri(resource) || typeof name !== 'string' || typeof viewType !== 'string') {
				return undefined;
			}
			// TODO@joh,peng this is disabled because the note-editor isn't fit for being
			// restorted (as it seems)
			if ('true') {
				return undefined;
			}
			return instantiationService.createInstance(NotebookEditorInput, resource, name, viewType);
		}
	}
);

85
export class NotebookContribution implements IWorkbenchContribution {
P
Peng Lyu 已提交
86
	private _resourceMapping: Map<string, NotebookEditorInput> = new Map<string, NotebookEditorInput>();
P
Peng Lyu 已提交
87 88 89

	constructor(
		@IEditorService private readonly editorService: IEditorService,
R
rebornix 已提交
90
		@INotebookService private readonly notebookService: INotebookService,
P
Peng Lyu 已提交
91
		@IInstantiationService private readonly instantiationService: IInstantiationService
92

P
Peng Lyu 已提交
93
	) {
P
Peng Lyu 已提交
94
		this.editorService.overrideOpenEditor((editor, options, group) => this.onEditorOpening(editor, options, group));
R
rebornix 已提交
95

R
rebornix 已提交
96 97 98
		this.editorService.onDidActiveEditorChange(() => {
			if (this.editorService.activeEditor && this.editorService.activeEditor! instanceof NotebookEditorInput) {
				let editorInput = this.editorService.activeEditor! as NotebookEditorInput;
J
Johannes Rieken 已提交
99
				this.notebookService.updateActiveNotebookDocument(editorInput.viewType!, editorInput.resource!);
R
rebornix 已提交
100 101
			}
		});
P
Peng Lyu 已提交
102 103
	}

104
	private onEditorOpening(editor: IEditorInput, options: IEditorOptions | ITextEditorOptions | undefined, group: IEditorGroup): IOpenEditorOverride | undefined {
J
Johannes Rieken 已提交
105
		const resource = editor.resource;
R
rebornix 已提交
106 107 108
		let viewType: string | undefined = undefined;

		if (resource) {
J
Johannes Rieken 已提交
109
			let notebookProviders = this.notebookService.getContributedNotebookProviders(resource);
110

R
rebornix 已提交
111 112 113
			if (notebookProviders.length > 0) {
				viewType = notebookProviders[0].id;
			}
114 115
		}

R
rebornix 已提交
116
		if (viewType === undefined) {
R
rebornix 已提交
117
			return undefined;
R
rebornix 已提交
118 119 120 121
		}

		if (this._resourceMapping.has(resource!.path)) {
			const input = this._resourceMapping.get(resource!.path);
P
Peng Lyu 已提交
122

R
rebornix 已提交
123 124 125
			if (!input!.isDisposed()) {
				return { override: this.editorService.openEditor(input!, { ...options, ignoreOverrides: true }, group) };
			}
P
Peng Lyu 已提交
126 127
		}

128
		const input = this.instantiationService.createInstance(NotebookEditorInput, editor.resource!, editor.getName(), viewType);
R
rebornix 已提交
129
		this._resourceMapping.set(resource!.path, input);
130

R
rebornix 已提交
131
		return { override: this.editorService.openEditor(input, options, group) };
P
Peng Lyu 已提交
132 133 134
	}
}

135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
class CellContentProvider implements ITextModelContentProvider {

	private readonly _registration: IDisposable;

	constructor(
		@ITextModelService textModelService: ITextModelService,
		@IModelService private readonly _modelService: IModelService,
		@IModeService private readonly _modeService: IModeService,
		@INotebookService private readonly _notebookService: INotebookService,
	) {
		this._registration = textModelService.registerTextModelContentProvider('vscode-notebook', this);
	}

	dispose(): void {
		this._registration.dispose();
	}

	async provideTextContent(resource: URI): Promise<ITextModel | null> {
		const data = parseCellUri(resource);
		if (!data) {
			return null;
		}
		const notebook = await this._notebookService.resolveNotebook(data.viewType, data.notebook);
		if (!notebook) {
			return null;
		}
		for (let cell of notebook.cells) {
162
			if (cell.uri.toString() === resource.toString()) {
163 164 165 166 167 168 169 170 171 172 173 174
				return this._modelService.createModel(
					cell.source.join('\n'),
					this._modeService.createByFilepathOrFirstLine(resource, cell.source[0]),
					resource
				);
			}
		}

		return null;
	}
}

175 176
const workbenchContributionsRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
workbenchContributionsRegistry.registerWorkbenchContribution(NotebookContribution, LifecyclePhase.Starting);
177
workbenchContributionsRegistry.registerWorkbenchContribution(CellContentProvider, LifecyclePhase.Starting);
R
rebornix 已提交
178 179

registerSingleton(INotebookService, NotebookService);
R
rebornix 已提交
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197

const configurationRegistry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);
configurationRegistry.registerConfiguration({
	id: 'notebook',
	order: 100,
	title: nls.localize('notebookConfigurationTitle', "Notebook"),
	type: 'object',
	properties: {
		'notebook.displayOrder': {
			markdownDescription: nls.localize('notebook.displayOrder.description', "Priority list for output mime types"),
			type: ['array'],
			items: {
				type: 'string'
			},
			default: []
		}
	}
});