@theia/notebook 1.46.1 → 1.47.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/contributions/notebook-actions-contribution.d.ts +3 -1
- package/lib/browser/contributions/notebook-actions-contribution.d.ts.map +1 -1
- package/lib/browser/contributions/notebook-actions-contribution.js +38 -37
- package/lib/browser/contributions/notebook-actions-contribution.js.map +1 -1
- package/lib/browser/contributions/notebook-cell-actions-contribution.d.ts +5 -1
- package/lib/browser/contributions/notebook-cell-actions-contribution.d.ts.map +1 -1
- package/lib/browser/contributions/notebook-cell-actions-contribution.js +29 -36
- package/lib/browser/contributions/notebook-cell-actions-contribution.js.map +1 -1
- package/lib/browser/contributions/notebook-color-contribution.js +2 -7
- package/lib/browser/contributions/notebook-color-contribution.js.map +1 -1
- package/lib/browser/index.js +12 -21
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/notebook-cell-resource-resolver.d.ts +10 -5
- package/lib/browser/notebook-cell-resource-resolver.d.ts.map +1 -1
- package/lib/browser/notebook-cell-resource-resolver.js +18 -17
- package/lib/browser/notebook-cell-resource-resolver.js.map +1 -1
- package/lib/browser/notebook-editor-widget-factory.js +10 -18
- package/lib/browser/notebook-editor-widget-factory.js.map +1 -1
- package/lib/browser/notebook-editor-widget.d.ts +20 -0
- package/lib/browser/notebook-editor-widget.d.ts.map +1 -1
- package/lib/browser/notebook-editor-widget.js +69 -32
- package/lib/browser/notebook-editor-widget.js.map +1 -1
- package/lib/browser/notebook-open-handler.js +4 -12
- package/lib/browser/notebook-open-handler.js.map +1 -1
- package/lib/browser/notebook-renderer-registry.d.ts +7 -0
- package/lib/browser/notebook-renderer-registry.d.ts.map +1 -1
- package/lib/browser/notebook-renderer-registry.js +13 -7
- package/lib/browser/notebook-renderer-registry.js.map +1 -1
- package/lib/browser/notebook-type-registry.js +2 -7
- package/lib/browser/notebook-type-registry.js.map +1 -1
- package/lib/browser/renderers/cell-output-webview.d.ts +2 -1
- package/lib/browser/renderers/cell-output-webview.d.ts.map +1 -1
- package/lib/browser/renderers/cell-output-webview.js.map +1 -1
- package/lib/browser/service/notebook-cell-context-manager.d.ts.map +1 -1
- package/lib/browser/service/notebook-cell-context-manager.js +6 -16
- package/lib/browser/service/notebook-cell-context-manager.js.map +1 -1
- package/lib/browser/service/notebook-editor-widget-service.js +8 -16
- package/lib/browser/service/notebook-editor-widget-service.js.map +1 -1
- package/lib/browser/service/notebook-execution-service.js +12 -20
- package/lib/browser/service/notebook-execution-service.js.map +1 -1
- package/lib/browser/service/notebook-execution-state-service.d.ts.map +1 -1
- package/lib/browser/service/notebook-execution-state-service.js +5 -14
- package/lib/browser/service/notebook-execution-state-service.js.map +1 -1
- package/lib/browser/service/notebook-kernel-history-service.js +12 -20
- package/lib/browser/service/notebook-kernel-history-service.js.map +1 -1
- package/lib/browser/service/notebook-kernel-quick-pick-service.js +12 -20
- package/lib/browser/service/notebook-kernel-quick-pick-service.js.map +1 -1
- package/lib/browser/service/notebook-kernel-service.d.ts +23 -12
- package/lib/browser/service/notebook-kernel-service.d.ts.map +1 -1
- package/lib/browser/service/notebook-kernel-service.js +11 -26
- package/lib/browser/service/notebook-kernel-service.js.map +1 -1
- package/lib/browser/service/notebook-model-resolver-service.d.ts +3 -2
- package/lib/browser/service/notebook-model-resolver-service.d.ts.map +1 -1
- package/lib/browser/service/notebook-model-resolver-service.js +21 -22
- package/lib/browser/service/notebook-model-resolver-service.js.map +1 -1
- package/lib/browser/service/notebook-renderer-messaging-service.d.ts +1 -0
- package/lib/browser/service/notebook-renderer-messaging-service.d.ts.map +1 -1
- package/lib/browser/service/notebook-renderer-messaging-service.js +12 -7
- package/lib/browser/service/notebook-renderer-messaging-service.js.map +1 -1
- package/lib/browser/service/notebook-service.d.ts +2 -2
- package/lib/browser/service/notebook-service.d.ts.map +1 -1
- package/lib/browser/service/notebook-service.js +13 -21
- package/lib/browser/service/notebook-service.js.map +1 -1
- package/lib/browser/view/notebook-cell-list-view.d.ts +3 -1
- package/lib/browser/view/notebook-cell-list-view.d.ts.map +1 -1
- package/lib/browser/view/notebook-cell-list-view.js +24 -7
- package/lib/browser/view/notebook-cell-list-view.js.map +1 -1
- package/lib/browser/view/notebook-cell-toolbar-factory.d.ts +1 -0
- package/lib/browser/view/notebook-cell-toolbar-factory.d.ts.map +1 -1
- package/lib/browser/view/notebook-cell-toolbar-factory.js +11 -18
- package/lib/browser/view/notebook-cell-toolbar-factory.js.map +1 -1
- package/lib/browser/view/notebook-cell-toolbar.js +2 -2
- package/lib/browser/view/notebook-cell-toolbar.js.map +1 -1
- package/lib/browser/view/notebook-code-cell-view.d.ts +6 -2
- package/lib/browser/view/notebook-code-cell-view.d.ts.map +1 -1
- package/lib/browser/view/notebook-code-cell-view.js +41 -30
- package/lib/browser/view/notebook-code-cell-view.js.map +1 -1
- package/lib/browser/view/notebook-main-toolbar.d.ts.map +1 -1
- package/lib/browser/view/notebook-main-toolbar.js +19 -22
- package/lib/browser/view/notebook-main-toolbar.js.map +1 -1
- package/lib/browser/view/notebook-markdown-cell-view.js +6 -14
- package/lib/browser/view/notebook-markdown-cell-view.js.map +1 -1
- package/lib/browser/view-model/notebook-cell-model.d.ts +1 -1
- package/lib/browser/view-model/notebook-cell-model.d.ts.map +1 -1
- package/lib/browser/view-model/notebook-cell-model.js +17 -22
- package/lib/browser/view-model/notebook-cell-model.js.map +1 -1
- package/lib/browser/view-model/notebook-model.d.ts +17 -14
- package/lib/browser/view-model/notebook-model.d.ts.map +1 -1
- package/lib/browser/view-model/notebook-model.js +30 -27
- package/lib/browser/view-model/notebook-model.js.map +1 -1
- package/lib/common/index.js +3 -12
- package/lib/common/index.js.map +1 -1
- package/lib/common/notebook-common.d.ts +1 -2
- package/lib/common/notebook-common.d.ts.map +1 -1
- package/lib/common/notebook-common.js.map +1 -1
- package/package.json +9 -8
- package/src/browser/contributions/notebook-actions-contribution.ts +41 -24
- package/src/browser/contributions/notebook-cell-actions-contribution.ts +24 -15
- package/src/browser/notebook-cell-resource-resolver.ts +24 -7
- package/src/browser/notebook-editor-widget.tsx +68 -6
- package/src/browser/notebook-renderer-registry.ts +19 -0
- package/src/browser/renderers/cell-output-webview.ts +2 -1
- package/src/browser/service/notebook-cell-context-manager.ts +0 -1
- package/src/browser/service/notebook-execution-state-service.ts +2 -3
- package/src/browser/service/notebook-kernel-service.ts +18 -21
- package/src/browser/service/notebook-model-resolver-service.ts +14 -10
- package/src/browser/service/notebook-renderer-messaging-service.ts +9 -1
- package/src/browser/service/notebook-service.ts +4 -4
- package/src/browser/style/index.css +17 -3
- package/src/browser/view/notebook-cell-list-view.tsx +34 -11
- package/src/browser/view/notebook-cell-toolbar-factory.tsx +2 -0
- package/src/browser/view/notebook-cell-toolbar.tsx +2 -2
- package/src/browser/view/notebook-code-cell-view.tsx +39 -14
- package/src/browser/view/notebook-main-toolbar.tsx +10 -4
- package/src/browser/view-model/notebook-cell-model.ts +5 -3
- package/src/browser/view-model/notebook-model.ts +27 -14
- package/src/common/notebook-common.ts +1 -2
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import * as React from '@theia/core/shared/react';
|
|
18
18
|
import { CommandRegistry, MenuModelRegistry, URI } from '@theia/core';
|
|
19
|
-
import { ReactWidget, Navigatable, SaveableSource, Message, DelegatingSaveable } from '@theia/core/lib/browser';
|
|
19
|
+
import { ReactWidget, Navigatable, SaveableSource, Message, DelegatingSaveable, lock, unlock } from '@theia/core/lib/browser';
|
|
20
20
|
import { ReactNode } from '@theia/core/shared/react';
|
|
21
21
|
import { CellKind } from '../common';
|
|
22
22
|
import { CellRenderer as CellRenderer, NotebookCellListView } from './view/notebook-cell-list-view';
|
|
@@ -29,6 +29,9 @@ import { Emitter } from '@theia/core/shared/vscode-languageserver-protocol';
|
|
|
29
29
|
import { NotebookEditorWidgetService } from './service/notebook-editor-widget-service';
|
|
30
30
|
import { NotebookMainToolbarRenderer } from './view/notebook-main-toolbar';
|
|
31
31
|
import { Deferred } from '@theia/core/lib/common/promise-util';
|
|
32
|
+
import { MarkdownString } from '@theia/core/lib/common/markdown-rendering';
|
|
33
|
+
|
|
34
|
+
const PerfectScrollbar = require('react-perfect-scrollbar');
|
|
32
35
|
|
|
33
36
|
export const NotebookEditorWidgetContainerFactory = Symbol('NotebookEditorWidgetContainerFactory');
|
|
34
37
|
|
|
@@ -43,6 +46,11 @@ export function createNotebookEditorWidgetContainer(parent: interfaces.Container
|
|
|
43
46
|
|
|
44
47
|
const NotebookEditorProps = Symbol('NotebookEditorProps');
|
|
45
48
|
|
|
49
|
+
interface RenderMessage {
|
|
50
|
+
rendererId: string;
|
|
51
|
+
message: unknown;
|
|
52
|
+
}
|
|
53
|
+
|
|
46
54
|
export interface NotebookEditorProps {
|
|
47
55
|
uri: URI,
|
|
48
56
|
readonly notebookType: string,
|
|
@@ -81,6 +89,21 @@ export class NotebookEditorWidget extends ReactWidget implements Navigatable, Sa
|
|
|
81
89
|
protected readonly onDidChangeModelEmitter = new Emitter<void>();
|
|
82
90
|
readonly onDidChangeModel = this.onDidChangeModelEmitter.event;
|
|
83
91
|
|
|
92
|
+
protected readonly onDidChangeReadOnlyEmitter = new Emitter<boolean | MarkdownString>();
|
|
93
|
+
readonly onDidChangeReadOnly = this.onDidChangeReadOnlyEmitter.event;
|
|
94
|
+
|
|
95
|
+
protected readonly onPostKernelMessageEmitter = new Emitter<unknown>();
|
|
96
|
+
readonly onPostKernelMessage = this.onPostKernelMessageEmitter.event;
|
|
97
|
+
|
|
98
|
+
protected readonly onDidPostKernelMessageEmitter = new Emitter<unknown>();
|
|
99
|
+
readonly onDidPostKernelMessage = this.onDidPostKernelMessageEmitter.event;
|
|
100
|
+
|
|
101
|
+
protected readonly onPostRendererMessageEmitter = new Emitter<RenderMessage>();
|
|
102
|
+
readonly onPostRendererMessage = this.onPostRendererMessageEmitter.event;
|
|
103
|
+
|
|
104
|
+
protected readonly onDidReceiveKernelMessageEmitter = new Emitter<unknown>();
|
|
105
|
+
readonly onDidRecieveKernelMessage = this.onDidReceiveKernelMessageEmitter.event;
|
|
106
|
+
|
|
84
107
|
protected readonly renderers = new Map<CellKind, CellRenderer>();
|
|
85
108
|
protected _model?: NotebookModel;
|
|
86
109
|
protected _ready: Deferred<NotebookModel> = new Deferred();
|
|
@@ -102,10 +125,15 @@ export class NotebookEditorWidget extends ReactWidget implements Navigatable, Sa
|
|
|
102
125
|
this.id = NOTEBOOK_EDITOR_ID_PREFIX + this.props.uri.toString();
|
|
103
126
|
this.node.tabIndex = -1;
|
|
104
127
|
|
|
128
|
+
this.scrollOptions = {
|
|
129
|
+
suppressScrollY: true
|
|
130
|
+
};
|
|
131
|
+
|
|
105
132
|
this.title.closable = true;
|
|
106
133
|
this.update();
|
|
107
134
|
|
|
108
135
|
this.toDispose.push(this.onDidChangeModelEmitter);
|
|
136
|
+
this.toDispose.push(this.onDidChangeReadOnlyEmitter);
|
|
109
137
|
|
|
110
138
|
this.renderers.set(CellKind.Markup, this.markdownCellRenderer);
|
|
111
139
|
this.renderers.set(CellKind.Code, this.codeCellRenderer);
|
|
@@ -116,6 +144,18 @@ export class NotebookEditorWidget extends ReactWidget implements Navigatable, Sa
|
|
|
116
144
|
this._model = await this.props.notebookData;
|
|
117
145
|
this.saveable.delegate = this._model;
|
|
118
146
|
this.toDispose.push(this._model);
|
|
147
|
+
this.toDispose.push(this._model.onDidChangeReadOnly(readOnly => {
|
|
148
|
+
if (readOnly) {
|
|
149
|
+
lock(this.title);
|
|
150
|
+
} else {
|
|
151
|
+
unlock(this.title);
|
|
152
|
+
}
|
|
153
|
+
this.onDidChangeReadOnlyEmitter.fire(readOnly);
|
|
154
|
+
this.update();
|
|
155
|
+
}));
|
|
156
|
+
if (this._model.readOnly) {
|
|
157
|
+
lock(this.title);
|
|
158
|
+
}
|
|
119
159
|
// Ensure that the model is loaded before adding the editor
|
|
120
160
|
this.notebookEditorService.addNotebookEditor(this);
|
|
121
161
|
this.update();
|
|
@@ -145,12 +185,14 @@ export class NotebookEditorWidget extends ReactWidget implements Navigatable, Sa
|
|
|
145
185
|
|
|
146
186
|
protected render(): ReactNode {
|
|
147
187
|
if (this._model) {
|
|
148
|
-
return <div>
|
|
188
|
+
return <div className='theia-notebook-main-container'>
|
|
149
189
|
{this.notebookMainToolbarRenderer.render(this._model)}
|
|
150
|
-
<
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
190
|
+
<PerfectScrollbar className='theia-notebook-scroll-container'>
|
|
191
|
+
<NotebookCellListView renderers={this.renderers}
|
|
192
|
+
notebookModel={this._model}
|
|
193
|
+
toolbarRenderer={this.cellToolbarFactory}
|
|
194
|
+
commandRegistry={this.commandRegistry} />
|
|
195
|
+
</PerfectScrollbar>
|
|
154
196
|
</div>;
|
|
155
197
|
} else {
|
|
156
198
|
return <div></div>;
|
|
@@ -165,4 +207,24 @@ export class NotebookEditorWidget extends ReactWidget implements Navigatable, Sa
|
|
|
165
207
|
super.onAfterDetach(msg);
|
|
166
208
|
this.notebookEditorService.removeNotebookEditor(this);
|
|
167
209
|
}
|
|
210
|
+
|
|
211
|
+
postKernelMessage(message: unknown): void {
|
|
212
|
+
this.onDidPostKernelMessageEmitter.fire(message);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
postRendererMessage(rendererId: string, message: unknown): void {
|
|
216
|
+
this.onPostRendererMessageEmitter.fire({ rendererId, message });
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
recieveKernelMessage(message: unknown): void {
|
|
220
|
+
this.onDidReceiveKernelMessageEmitter.fire(message);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
override dispose(): void {
|
|
224
|
+
this.onDidChangeModelEmitter.dispose();
|
|
225
|
+
this.onDidPostKernelMessageEmitter.dispose();
|
|
226
|
+
this.onDidReceiveKernelMessageEmitter.dispose();
|
|
227
|
+
this.onPostRendererMessageEmitter.dispose();
|
|
228
|
+
super.dispose();
|
|
229
|
+
}
|
|
168
230
|
}
|
|
@@ -30,6 +30,11 @@ export interface NotebookRendererInfo {
|
|
|
30
30
|
readonly requiresMessaging: boolean;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
export interface NotebookPreloadInfo {
|
|
34
|
+
readonly type: string;
|
|
35
|
+
readonly entrypoint: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
33
38
|
@injectable()
|
|
34
39
|
export class NotebookRendererRegistry {
|
|
35
40
|
|
|
@@ -39,6 +44,12 @@ export class NotebookRendererRegistry {
|
|
|
39
44
|
return this._notebookRenderers;
|
|
40
45
|
}
|
|
41
46
|
|
|
47
|
+
private readonly _staticNotebookPreloads: NotebookPreloadInfo[] = [];
|
|
48
|
+
|
|
49
|
+
get staticNotebookPreloads(): readonly NotebookPreloadInfo[] {
|
|
50
|
+
return this._staticNotebookPreloads;
|
|
51
|
+
}
|
|
52
|
+
|
|
42
53
|
registerNotebookRenderer(type: NotebookRendererDescriptor, basePath: string): Disposable {
|
|
43
54
|
let entrypoint;
|
|
44
55
|
if (typeof type.entrypoint === 'string') {
|
|
@@ -62,5 +73,13 @@ export class NotebookRendererRegistry {
|
|
|
62
73
|
this._notebookRenderers.splice(this._notebookRenderers.findIndex(renderer => renderer.id === type.id), 1);
|
|
63
74
|
});
|
|
64
75
|
}
|
|
76
|
+
|
|
77
|
+
registerStaticNotebookPreload(type: string, entrypoint: string, basePath: string): Disposable {
|
|
78
|
+
const staticPreload = { type, entrypoint: new Path(basePath).join(entrypoint).toString() };
|
|
79
|
+
this._staticNotebookPreloads.push(staticPreload);
|
|
80
|
+
return Disposable.create(() => {
|
|
81
|
+
this._staticNotebookPreloads.splice(this._staticNotebookPreloads.indexOf(staticPreload), 1);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
65
84
|
}
|
|
66
85
|
|
|
@@ -16,10 +16,11 @@
|
|
|
16
16
|
|
|
17
17
|
import { Disposable } from '@theia/core';
|
|
18
18
|
import { NotebookCellModel } from '../view-model/notebook-cell-model';
|
|
19
|
+
import { NotebookModel } from '../view-model/notebook-model';
|
|
19
20
|
|
|
20
21
|
export const CellOutputWebviewFactory = Symbol('outputWebviewFactory');
|
|
21
22
|
|
|
22
|
-
export type CellOutputWebviewFactory = (cell: NotebookCellModel) => Promise<CellOutputWebview>;
|
|
23
|
+
export type CellOutputWebviewFactory = (cell: NotebookCellModel, notebook: NotebookModel) => Promise<CellOutputWebview>;
|
|
23
24
|
|
|
24
25
|
export interface CellOutputWebview extends Disposable {
|
|
25
26
|
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
19
19
|
*--------------------------------------------------------------------------------------------*/
|
|
20
20
|
|
|
21
|
-
import { Disposable, DisposableCollection, Emitter, URI } from '@theia/core';
|
|
21
|
+
import { Disposable, DisposableCollection, Emitter, URI, generateUuid } from '@theia/core';
|
|
22
22
|
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
23
23
|
import { NotebookService } from './notebook-service';
|
|
24
24
|
import {
|
|
@@ -27,7 +27,6 @@ import {
|
|
|
27
27
|
} from '../../common';
|
|
28
28
|
import { CellPartialInternalMetadataEditByHandle, CellEditOperation } from '../notebook-types';
|
|
29
29
|
import { NotebookModel } from '../view-model/notebook-model';
|
|
30
|
-
import { v4 } from 'uuid';
|
|
31
30
|
|
|
32
31
|
export type CellExecuteUpdate = CellExecuteOutputEdit | CellExecuteOutputItemEdit | CellExecutionStateUpdate;
|
|
33
32
|
|
|
@@ -178,7 +177,7 @@ export class CellExecution implements Disposable {
|
|
|
178
177
|
editType: CellEditType.PartialInternalMetadata,
|
|
179
178
|
handle: this.cellHandle,
|
|
180
179
|
internalMetadata: {
|
|
181
|
-
executionId:
|
|
180
|
+
executionId: generateUuid(),
|
|
182
181
|
runStartTime: undefined,
|
|
183
182
|
runEndTime: undefined,
|
|
184
183
|
lastRunSuccess: undefined,
|
|
@@ -54,6 +54,11 @@ export interface NotebookKernel {
|
|
|
54
54
|
// ID of the extension providing this kernel
|
|
55
55
|
readonly extensionId: string;
|
|
56
56
|
|
|
57
|
+
readonly localResourceRoot: URI;
|
|
58
|
+
readonly preloadUris: URI[];
|
|
59
|
+
readonly preloadProvides: string[];
|
|
60
|
+
|
|
61
|
+
readonly handle: number;
|
|
57
62
|
label: string;
|
|
58
63
|
description?: string;
|
|
59
64
|
detail?: string;
|
|
@@ -144,7 +149,7 @@ export class SourceCommand implements Disposable {
|
|
|
144
149
|
|
|
145
150
|
const NOTEBOOK_KERNEL_BINDING_STORAGE_KEY = 'notebook.kernel.bindings';
|
|
146
151
|
@injectable()
|
|
147
|
-
export class NotebookKernelService
|
|
152
|
+
export class NotebookKernelService {
|
|
148
153
|
|
|
149
154
|
@inject(NotebookService)
|
|
150
155
|
protected notebookService: NotebookService;
|
|
@@ -152,33 +157,34 @@ export class NotebookKernelService implements Disposable {
|
|
|
152
157
|
@inject(StorageService)
|
|
153
158
|
protected storageService: StorageService;
|
|
154
159
|
|
|
155
|
-
|
|
160
|
+
protected readonly kernels = new Map<string, KernelInfo>();
|
|
156
161
|
|
|
157
|
-
|
|
162
|
+
protected notebookBindings: Record<string, string> = {};
|
|
158
163
|
|
|
159
|
-
|
|
160
|
-
|
|
164
|
+
protected readonly kernelDetectionTasks = new Map<string, string[]>();
|
|
165
|
+
protected readonly onDidChangeKernelDetectionTasksEmitter = new Emitter<string>();
|
|
161
166
|
readonly onDidChangeKernelDetectionTasks = this.onDidChangeKernelDetectionTasksEmitter.event;
|
|
162
167
|
|
|
163
|
-
|
|
164
|
-
|
|
168
|
+
protected readonly onDidChangeSourceActionsEmitter = new Emitter<NotebookSourceActionChangeEvent>();
|
|
169
|
+
protected readonly kernelSourceActionProviders = new Map<string, KernelSourceActionProvider[]>();
|
|
165
170
|
readonly onDidChangeSourceActions: Event<NotebookSourceActionChangeEvent> = this.onDidChangeSourceActionsEmitter.event;
|
|
166
171
|
|
|
167
|
-
|
|
172
|
+
protected readonly onDidAddKernelEmitter = new Emitter<NotebookKernel>();
|
|
168
173
|
readonly onDidAddKernel: Event<NotebookKernel> = this.onDidAddKernelEmitter.event;
|
|
169
174
|
|
|
170
|
-
|
|
175
|
+
protected readonly onDidRemoveKernelEmitter = new Emitter<NotebookKernel>();
|
|
171
176
|
readonly onDidRemoveKernel: Event<NotebookKernel> = this.onDidRemoveKernelEmitter.event;
|
|
172
177
|
|
|
173
|
-
|
|
178
|
+
protected readonly onDidChangeSelectedNotebookKernelBindingEmitter = new Emitter<SelectedNotebookKernelChangeEvent>();
|
|
174
179
|
readonly onDidChangeSelectedKernel: Event<SelectedNotebookKernelChangeEvent> = this.onDidChangeSelectedNotebookKernelBindingEmitter.event;
|
|
175
180
|
|
|
176
|
-
|
|
181
|
+
protected readonly onDidChangeNotebookAffinityEmitter = new Emitter<void>();
|
|
177
182
|
readonly onDidChangeNotebookAffinity: Event<void> = this.onDidChangeNotebookAffinityEmitter.event;
|
|
178
183
|
|
|
179
184
|
@postConstruct()
|
|
180
185
|
init(): void {
|
|
181
|
-
this.
|
|
186
|
+
this.notebookService.onDidAddNotebookDocument(model => this.tryAutoBindNotebook(model));
|
|
187
|
+
this.storageService.getData(NOTEBOOK_KERNEL_BINDING_STORAGE_KEY).then((value: Record<string, string> | undefined) => {
|
|
182
188
|
if (value) {
|
|
183
189
|
this.notebookBindings = value;
|
|
184
190
|
}
|
|
@@ -344,13 +350,4 @@ export class NotebookKernelService implements Disposable {
|
|
|
344
350
|
const allActions = await Promise.all(promises);
|
|
345
351
|
return allActions.flat();
|
|
346
352
|
}
|
|
347
|
-
|
|
348
|
-
dispose(): void {
|
|
349
|
-
this.onDidChangeKernelDetectionTasksEmitter.dispose();
|
|
350
|
-
this.onDidChangeSourceActionsEmitter.dispose();
|
|
351
|
-
this.onDidAddKernelEmitter.dispose();
|
|
352
|
-
this.onDidRemoveKernelEmitter.dispose();
|
|
353
|
-
this.onDidChangeSelectedNotebookKernelBindingEmitter.dispose();
|
|
354
|
-
this.onDidChangeNotebookAffinityEmitter.dispose();
|
|
355
|
-
}
|
|
356
353
|
}
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import { Emitter, URI } from '@theia/core';
|
|
17
|
+
import { Emitter, Resource, ResourceProvider, URI } from '@theia/core';
|
|
18
18
|
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
19
19
|
import { UriComponents } from '@theia/core/lib/common/uri';
|
|
20
20
|
import { FileService } from '@theia/filesystem/lib/browser/file-service';
|
|
@@ -34,6 +34,9 @@ export class NotebookModelResolverService {
|
|
|
34
34
|
@inject(FileService)
|
|
35
35
|
protected fileService: FileService;
|
|
36
36
|
|
|
37
|
+
@inject(ResourceProvider)
|
|
38
|
+
protected resourceProvider: ResourceProvider;
|
|
39
|
+
|
|
37
40
|
@inject(NotebookService)
|
|
38
41
|
protected notebookService: NotebookService;
|
|
39
42
|
|
|
@@ -60,9 +63,9 @@ export class NotebookModelResolverService {
|
|
|
60
63
|
throw new Error(`Missing viewType for '${resource}'`);
|
|
61
64
|
}
|
|
62
65
|
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
const notebookModel = await this.notebookService.createNotebookModel(notebookData, viewType,
|
|
66
|
+
const actualResource = await this.resourceProvider(resource);
|
|
67
|
+
const notebookData = await this.resolveExistingNotebookData(actualResource, viewType!);
|
|
68
|
+
const notebookModel = await this.notebookService.createNotebookModel(notebookData, viewType, actualResource);
|
|
66
69
|
|
|
67
70
|
notebookModel.onDirtyChanged(() => this.onDidChangeDirtyEmitter.fire(notebookModel));
|
|
68
71
|
notebookModel.onDidSaveNotebook(() => this.onDidSaveNotebookEmitter.fire(notebookModel.uri.toComponents()));
|
|
@@ -103,8 +106,8 @@ export class NotebookModelResolverService {
|
|
|
103
106
|
return this.resolve(resource, viewType);
|
|
104
107
|
}
|
|
105
108
|
|
|
106
|
-
protected async resolveExistingNotebookData(resource:
|
|
107
|
-
if (resource.scheme === 'untitled') {
|
|
109
|
+
protected async resolveExistingNotebookData(resource: Resource, viewType: string): Promise<NotebookData> {
|
|
110
|
+
if (resource.uri.scheme === 'untitled') {
|
|
108
111
|
|
|
109
112
|
return {
|
|
110
113
|
cells: [
|
|
@@ -118,10 +121,11 @@ export class NotebookModelResolverService {
|
|
|
118
121
|
metadata: {}
|
|
119
122
|
};
|
|
120
123
|
} else {
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
124
|
+
const [dataProvider, contents] = await Promise.all([
|
|
125
|
+
this.notebookService.getNotebookDataProvider(viewType),
|
|
126
|
+
this.fileService.readFile(resource.uri)
|
|
127
|
+
]);
|
|
128
|
+
const notebook = await dataProvider.serializer.toNotebook(contents.value);
|
|
125
129
|
|
|
126
130
|
return notebook;
|
|
127
131
|
}
|
|
@@ -19,8 +19,9 @@
|
|
|
19
19
|
*--------------------------------------------------------------------------------------------*/
|
|
20
20
|
|
|
21
21
|
import { Emitter } from '@theia/core';
|
|
22
|
-
import { injectable } from '@theia/core/shared/inversify';
|
|
22
|
+
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
23
23
|
import { Disposable } from '@theia/core/shared/vscode-languageserver-protocol';
|
|
24
|
+
import { NotebookEditorWidgetService } from './notebook-editor-widget-service';
|
|
24
25
|
|
|
25
26
|
interface RendererMessage {
|
|
26
27
|
editorId: string;
|
|
@@ -50,6 +51,9 @@ export class NotebookRendererMessagingService implements Disposable {
|
|
|
50
51
|
private readonly willActivateRendererEmitter = new Emitter<string>();
|
|
51
52
|
readonly onWillActivateRenderer = this.willActivateRendererEmitter.event;
|
|
52
53
|
|
|
54
|
+
@inject(NotebookEditorWidgetService)
|
|
55
|
+
private readonly editorWidgetService: NotebookEditorWidgetService;
|
|
56
|
+
|
|
53
57
|
private readonly activations = new Map<string /* rendererId */, undefined | RendererMessage[]>();
|
|
54
58
|
private readonly scopedMessaging = new Map<string /* editorId */, RendererMessaging>();
|
|
55
59
|
|
|
@@ -86,6 +90,10 @@ export class NotebookRendererMessagingService implements Disposable {
|
|
|
86
90
|
|
|
87
91
|
const messaging: RendererMessaging = {
|
|
88
92
|
postMessage: (rendererId, message) => this.postMessage(editorId, rendererId, message),
|
|
93
|
+
receiveMessage: async (rendererId, message) => {
|
|
94
|
+
this.editorWidgetService.getNotebookEditor(editorId)?.postRendererMessage(rendererId, message);
|
|
95
|
+
return true;
|
|
96
|
+
},
|
|
89
97
|
dispose: () => this.scopedMessaging.delete(editorId),
|
|
90
98
|
};
|
|
91
99
|
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import { Disposable, DisposableCollection, Emitter, URI } from '@theia/core';
|
|
17
|
+
import { Disposable, DisposableCollection, Emitter, Resource, URI } from '@theia/core';
|
|
18
18
|
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
19
19
|
import { BinaryBuffer } from '@theia/core/lib/common/buffer';
|
|
20
20
|
import { NotebookData, TransientOptions } from '../../common';
|
|
@@ -101,14 +101,14 @@ export class NotebookService implements Disposable {
|
|
|
101
101
|
});
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
async createNotebookModel(data: NotebookData, viewType: string,
|
|
104
|
+
async createNotebookModel(data: NotebookData, viewType: string, resource: Resource): Promise<NotebookModel> {
|
|
105
105
|
const serializer = this.notebookProviders.get(viewType)?.serializer;
|
|
106
106
|
if (!serializer) {
|
|
107
107
|
throw new Error('no notebook serializer for ' + viewType);
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
const model = this.notebookModelFactory({ data,
|
|
111
|
-
this.notebookModels.set(uri.toString(), model);
|
|
110
|
+
const model = this.notebookModelFactory({ data, resource, viewType, serializer });
|
|
111
|
+
this.notebookModels.set(resource.uri.toString(), model);
|
|
112
112
|
// Resolve cell text models right after creating the notebook model
|
|
113
113
|
// This ensures that all text models are available in the plugin host
|
|
114
114
|
await Promise.all(model.cells.map(e => e.resolveTextModel()));
|
|
@@ -26,11 +26,14 @@
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
.theia-notebook-cell {
|
|
29
|
-
cursor: grab;
|
|
30
29
|
display: flex;
|
|
31
30
|
margin: 10px 0px;
|
|
32
31
|
}
|
|
33
32
|
|
|
33
|
+
.theia-notebook-cell.draggable {
|
|
34
|
+
cursor: grab;
|
|
35
|
+
}
|
|
36
|
+
|
|
34
37
|
.theia-notebook-cell:hover .theia-notebook-cell-marker {
|
|
35
38
|
visibility: visible;
|
|
36
39
|
}
|
|
@@ -161,9 +164,20 @@
|
|
|
161
164
|
flex-direction: column;
|
|
162
165
|
}
|
|
163
166
|
|
|
167
|
+
.theia-notebook-main-container {
|
|
168
|
+
display: flex;
|
|
169
|
+
flex-direction: column;
|
|
170
|
+
height: 100%;
|
|
171
|
+
overflow: hidden;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.theia-notebook-scroll-container {
|
|
175
|
+
flex: 1;
|
|
176
|
+
overflow: hidden;
|
|
177
|
+
position: relative;
|
|
178
|
+
}
|
|
179
|
+
|
|
164
180
|
.theia-notebook-main-toolbar {
|
|
165
|
-
position: sticky;
|
|
166
|
-
top: 0;
|
|
167
181
|
background: var(--theia-editor-background);
|
|
168
182
|
display: flex;
|
|
169
183
|
flex-direction: row;
|
|
@@ -64,11 +64,13 @@ export class NotebookCellListView extends React.Component<CellListProps, Noteboo
|
|
|
64
64
|
{this.props.notebookModel.cells
|
|
65
65
|
.map((cell, index) =>
|
|
66
66
|
<React.Fragment key={'cell-' + cell.handle}>
|
|
67
|
-
<NotebookCellDivider
|
|
67
|
+
<NotebookCellDivider
|
|
68
|
+
isVisible={() => this.isEnabled()}
|
|
69
|
+
onAddNewCell={(kind: CellKind) => this.onAddNewCell(kind, index)}
|
|
68
70
|
onDrop={e => this.onDrop(e, index)}
|
|
69
71
|
onDragOver={e => this.onDragOver(e, cell, 'top')} />
|
|
70
72
|
{this.shouldRenderDragOverIndicator(cell, 'top') && <CellDropIndicator />}
|
|
71
|
-
<li className={'theia-notebook-cell' + (this.state.selectedCell === cell ? ' focused' : '')}
|
|
73
|
+
<li className={'theia-notebook-cell' + (this.state.selectedCell === cell ? ' focused' : '') + (this.isEnabled() ? ' draggable' : '')}
|
|
72
74
|
onClick={() => {
|
|
73
75
|
this.setState({ selectedCell: cell });
|
|
74
76
|
this.props.notebookModel.setSelectedCell(cell);
|
|
@@ -89,7 +91,9 @@ export class NotebookCellListView extends React.Component<CellListProps, Noteboo
|
|
|
89
91
|
</React.Fragment>
|
|
90
92
|
)
|
|
91
93
|
}
|
|
92
|
-
<NotebookCellDivider
|
|
94
|
+
<NotebookCellDivider
|
|
95
|
+
isVisible={() => this.isEnabled()}
|
|
96
|
+
onAddNewCell={(kind: CellKind) => this.onAddNewCell(kind, this.props.notebookModel.cells.length)}
|
|
93
97
|
onDrop={e => this.onDrop(e, this.props.notebookModel.cells.length - 1)}
|
|
94
98
|
onDragOver={e => this.onDragOver(e, this.props.notebookModel.cells[this.props.notebookModel.cells.length - 1], 'bottom')} />
|
|
95
99
|
</ul>;
|
|
@@ -105,18 +109,33 @@ export class NotebookCellListView extends React.Component<CellListProps, Noteboo
|
|
|
105
109
|
|
|
106
110
|
protected onDragStart(event: React.DragEvent<HTMLLIElement>, index: number): void {
|
|
107
111
|
event.stopPropagation();
|
|
112
|
+
if (!this.isEnabled()) {
|
|
113
|
+
event.preventDefault();
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
108
116
|
event.dataTransfer.setData('text/theia-notebook-cell-index', index.toString());
|
|
109
117
|
event.dataTransfer.setData('text/plain', this.props.notebookModel.cells[index].source);
|
|
110
118
|
}
|
|
111
119
|
|
|
112
120
|
protected onDragOver(event: React.DragEvent<HTMLLIElement>, cell: NotebookCellModel, position?: 'top' | 'bottom'): void {
|
|
121
|
+
if (!this.isEnabled()) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
113
124
|
event.preventDefault();
|
|
114
125
|
event.stopPropagation();
|
|
115
126
|
// show indicator
|
|
116
127
|
this.setState({ ...this.state, dragOverIndicator: { cell, position: position ?? event.nativeEvent.offsetY < event.currentTarget.clientHeight / 2 ? 'top' : 'bottom' } });
|
|
117
128
|
}
|
|
118
129
|
|
|
130
|
+
protected isEnabled(): boolean {
|
|
131
|
+
return !Boolean(this.props.notebookModel.readOnly);
|
|
132
|
+
}
|
|
133
|
+
|
|
119
134
|
protected onDrop(event: React.DragEvent<HTMLLIElement>, dropElementIndex: number): void {
|
|
135
|
+
if (!this.isEnabled()) {
|
|
136
|
+
this.setState({ dragOverIndicator: undefined });
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
120
139
|
const index = parseInt(event.dataTransfer.getData('text/theia-notebook-cell-index'));
|
|
121
140
|
const isTargetBelow = index < dropElementIndex;
|
|
122
141
|
let newIdx = this.state.dragOverIndicator?.position === 'top' ? dropElementIndex : dropElementIndex + 1;
|
|
@@ -133,15 +152,18 @@ export class NotebookCellListView extends React.Component<CellListProps, Noteboo
|
|
|
133
152
|
}
|
|
134
153
|
|
|
135
154
|
protected onAddNewCell(kind: CellKind, index: number): void {
|
|
136
|
-
this.
|
|
137
|
-
this.props.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
155
|
+
if (this.isEnabled()) {
|
|
156
|
+
this.props.commandRegistry.executeCommand(NotebookCommands.ADD_NEW_CELL_COMMAND.id,
|
|
157
|
+
this.props.notebookModel,
|
|
158
|
+
kind,
|
|
159
|
+
index
|
|
160
|
+
);
|
|
161
|
+
}
|
|
141
162
|
}
|
|
142
163
|
|
|
143
164
|
protected shouldRenderDragOverIndicator(cell: NotebookCellModel, position: 'top' | 'bottom'): boolean {
|
|
144
|
-
return this.
|
|
165
|
+
return this.isEnabled() &&
|
|
166
|
+
this.state.dragOverIndicator !== undefined &&
|
|
145
167
|
this.state.dragOverIndicator.cell === cell &&
|
|
146
168
|
this.state.dragOverIndicator.position === position;
|
|
147
169
|
}
|
|
@@ -149,16 +171,17 @@ export class NotebookCellListView extends React.Component<CellListProps, Noteboo
|
|
|
149
171
|
}
|
|
150
172
|
|
|
151
173
|
export interface NotebookCellDividerProps {
|
|
174
|
+
isVisible: () => boolean;
|
|
152
175
|
onAddNewCell: (type: CellKind) => void;
|
|
153
176
|
onDrop: (event: React.DragEvent<HTMLLIElement>) => void;
|
|
154
177
|
onDragOver: (event: React.DragEvent<HTMLLIElement>) => void;
|
|
155
178
|
}
|
|
156
179
|
|
|
157
|
-
export function NotebookCellDivider({ onAddNewCell, onDrop, onDragOver }: NotebookCellDividerProps): React.JSX.Element {
|
|
180
|
+
export function NotebookCellDivider({ isVisible, onAddNewCell, onDrop, onDragOver }: NotebookCellDividerProps): React.JSX.Element {
|
|
158
181
|
const [hover, setHover] = React.useState(false);
|
|
159
182
|
|
|
160
183
|
return <li className='theia-notebook-cell-divider' onMouseEnter={() => setHover(true)} onMouseLeave={() => setHover(false)} onDrop={onDrop} onDragOver={onDragOver}>
|
|
161
|
-
{hover && <div className='theia-notebook-add-cell-buttons'>
|
|
184
|
+
{hover && isVisible() && <div className='theia-notebook-add-cell-buttons'>
|
|
162
185
|
<button className='theia-notebook-add-cell-button' onClick={() => onAddNewCell(CellKind.Code)} title={nls.localizeByDefault('Add Code Cell')}>
|
|
163
186
|
<div className={codicon('add') + ' theia-notebook-add-cell-button-icon'} />
|
|
164
187
|
{nls.localizeByDefault('Code')}
|
|
@@ -29,6 +29,7 @@ export interface NotebookCellToolbarItem {
|
|
|
29
29
|
icon?: string;
|
|
30
30
|
label?: string;
|
|
31
31
|
onClick: (e: React.MouseEvent) => void;
|
|
32
|
+
isVisible: () => boolean;
|
|
32
33
|
contextKeys?: Set<string>
|
|
33
34
|
}
|
|
34
35
|
|
|
@@ -87,6 +88,7 @@ export class NotebookCellToolbarFactory {
|
|
|
87
88
|
args: [notebookModel, cell, output]
|
|
88
89
|
}) :
|
|
89
90
|
() => this.commandRegistry.executeCommand(menuNode.command!, notebookModel, cell, output),
|
|
91
|
+
isVisible: () => menuPath ? true : Boolean(this.commandRegistry.getVisibleHandler(menuNode.command!, notebookModel, cell, output)),
|
|
90
92
|
contextKeys: menuNode.when ? this.contextKeyService.parseKeys(menuNode.when) : undefined
|
|
91
93
|
};
|
|
92
94
|
}
|
|
@@ -56,7 +56,7 @@ export class NotebookCellToolbar extends NotebookCellActionBar {
|
|
|
56
56
|
|
|
57
57
|
override render(): React.ReactNode {
|
|
58
58
|
return <div className='theia-notebook-cell-toolbar'>
|
|
59
|
-
{this.state.inlineItems.map(item => this.renderItem(item))}
|
|
59
|
+
{this.state.inlineItems.filter(e => e.isVisible()).map(item => this.renderItem(item))}
|
|
60
60
|
</div>;
|
|
61
61
|
}
|
|
62
62
|
|
|
@@ -66,7 +66,7 @@ export class NotebookCellSidebar extends NotebookCellActionBar {
|
|
|
66
66
|
|
|
67
67
|
override render(): React.ReactNode {
|
|
68
68
|
return <div className='theia-notebook-cell-sidebar'>
|
|
69
|
-
{this.state.inlineItems.map(item => this.renderItem(item))}
|
|
69
|
+
{this.state.inlineItems.filter(e => e.isVisible()).map(item => this.renderItem(item))}
|
|
70
70
|
</div>;
|
|
71
71
|
}
|
|
72
72
|
}
|