@theia/notebook 1.43.1 → 1.45.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 +2 -2
- package/lib/browser/contributions/notebook-actions-contribution.d.ts.map +1 -1
- package/lib/browser/contributions/notebook-actions-contribution.js +1 -1
- package/lib/browser/contributions/notebook-actions-contribution.js.map +1 -1
- package/lib/browser/index.d.ts +1 -0
- package/lib/browser/index.d.ts.map +1 -1
- package/lib/browser/index.js +1 -0
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/notebook-editor-widget.d.ts +4 -1
- package/lib/browser/notebook-editor-widget.d.ts.map +1 -1
- package/lib/browser/notebook-editor-widget.js +9 -3
- package/lib/browser/notebook-editor-widget.js.map +1 -1
- package/lib/browser/notebook-frontend-module.js +1 -1
- package/lib/browser/notebook-frontend-module.js.map +1 -1
- package/lib/browser/notebook-output-utils.d.ts +13 -0
- package/lib/browser/notebook-output-utils.d.ts.map +1 -0
- package/lib/browser/notebook-output-utils.js +112 -0
- package/lib/browser/notebook-output-utils.js.map +1 -0
- package/lib/browser/notebook-types.d.ts +120 -0
- package/lib/browser/notebook-types.d.ts.map +1 -0
- package/lib/browser/notebook-types.js +28 -0
- package/lib/browser/notebook-types.js.map +1 -0
- package/lib/browser/service/notebook-cell-context-manager.d.ts +5 -4
- package/lib/browser/service/notebook-cell-context-manager.d.ts.map +1 -1
- package/lib/browser/service/notebook-cell-context-manager.js +15 -10
- package/lib/browser/service/notebook-cell-context-manager.js.map +1 -1
- package/lib/browser/service/notebook-editor-widget-service.d.ts +2 -5
- package/lib/browser/service/notebook-editor-widget-service.d.ts.map +1 -1
- package/lib/browser/service/notebook-editor-widget-service.js +12 -15
- package/lib/browser/service/notebook-editor-widget-service.js.map +1 -1
- package/lib/browser/service/notebook-execution-service.d.ts +3 -4
- package/lib/browser/service/notebook-execution-service.d.ts.map +1 -1
- package/lib/browser/service/notebook-execution-service.js +2 -12
- package/lib/browser/service/notebook-execution-service.js.map +1 -1
- package/lib/browser/service/notebook-execution-state-service.d.ts +2 -5
- package/lib/browser/service/notebook-execution-state-service.d.ts.map +1 -1
- package/lib/browser/service/notebook-execution-state-service.js.map +1 -1
- package/lib/browser/service/notebook-kernel-history-service.d.ts +4 -1
- package/lib/browser/service/notebook-kernel-history-service.d.ts.map +1 -1
- package/lib/browser/service/notebook-kernel-history-service.js +15 -0
- package/lib/browser/service/notebook-kernel-history-service.js.map +1 -1
- package/lib/browser/service/notebook-kernel-quick-pick-service.d.ts +5 -11
- package/lib/browser/service/notebook-kernel-quick-pick-service.d.ts.map +1 -1
- package/lib/browser/service/notebook-kernel-quick-pick-service.js +33 -48
- package/lib/browser/service/notebook-kernel-quick-pick-service.js.map +1 -1
- package/lib/browser/service/notebook-service.d.ts.map +1 -1
- package/lib/browser/service/notebook-service.js +9 -4
- package/lib/browser/service/notebook-service.js.map +1 -1
- package/lib/browser/view/notebook-cell-editor.d.ts +1 -1
- package/lib/browser/view/notebook-cell-editor.d.ts.map +1 -1
- package/lib/browser/view/notebook-cell-editor.js +5 -5
- package/lib/browser/view/notebook-cell-editor.js.map +1 -1
- package/lib/browser/view/notebook-cell-list-view.d.ts.map +1 -1
- package/lib/browser/view/notebook-cell-list-view.js +9 -3
- 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 +2 -1
- package/lib/browser/view/notebook-cell-toolbar-factory.js.map +1 -1
- package/lib/browser/view/notebook-cell-toolbar.d.ts +5 -4
- package/lib/browser/view/notebook-cell-toolbar.d.ts.map +1 -1
- package/lib/browser/view/notebook-cell-toolbar.js +6 -4
- package/lib/browser/view/notebook-cell-toolbar.js.map +1 -1
- package/lib/browser/view/notebook-main-toolbar.d.ts.map +1 -1
- package/lib/browser/view/notebook-main-toolbar.js +8 -0
- package/lib/browser/view/notebook-main-toolbar.js.map +1 -1
- package/lib/browser/view-model/notebook-cell-model.d.ts +22 -2
- package/lib/browser/view-model/notebook-cell-model.d.ts.map +1 -1
- package/lib/browser/view-model/notebook-cell-model.js +5 -0
- package/lib/browser/view-model/notebook-cell-model.js.map +1 -1
- package/lib/browser/view-model/notebook-cell-output-model.d.ts.map +1 -1
- package/lib/browser/view-model/notebook-cell-output-model.js +4 -3
- package/lib/browser/view-model/notebook-cell-output-model.js.map +1 -1
- package/lib/browser/view-model/notebook-model.d.ts +9 -7
- package/lib/browser/view-model/notebook-model.d.ts.map +1 -1
- package/lib/browser/view-model/notebook-model.js +42 -36
- package/lib/browser/view-model/notebook-model.js.map +1 -1
- package/lib/common/notebook-common.d.ts +14 -146
- package/lib/common/notebook-common.d.ts.map +1 -1
- package/lib/common/notebook-common.js +13 -9
- package/lib/common/notebook-common.js.map +1 -1
- package/package.json +7 -7
- package/src/browser/contributions/notebook-actions-contribution.ts +2 -2
- package/src/browser/index.ts +1 -0
- package/src/browser/notebook-editor-widget.tsx +11 -5
- package/src/browser/notebook-frontend-module.ts +2 -2
- package/src/browser/notebook-output-utils.ts +119 -0
- package/src/browser/notebook-types.ts +172 -0
- package/src/browser/service/notebook-cell-context-manager.ts +17 -12
- package/src/browser/service/notebook-editor-widget-service.ts +14 -19
- package/src/browser/service/notebook-execution-service.ts +4 -16
- package/src/browser/service/notebook-execution-state-service.ts +2 -5
- package/src/browser/service/notebook-kernel-history-service.ts +18 -1
- package/src/browser/service/notebook-kernel-quick-pick-service.ts +29 -49
- package/src/browser/service/notebook-service.ts +13 -4
- package/src/browser/view/notebook-cell-editor.tsx +7 -5
- package/src/browser/view/notebook-cell-list-view.tsx +8 -3
- package/src/browser/view/notebook-cell-toolbar-factory.tsx +3 -1
- package/src/browser/view/notebook-cell-toolbar.tsx +8 -5
- package/src/browser/view/notebook-main-toolbar.tsx +9 -0
- package/src/browser/view-model/notebook-cell-model.ts +30 -3
- package/src/browser/view-model/notebook-cell-output-model.ts +6 -5
- package/src/browser/view-model/notebook-model.ts +52 -45
- package/src/common/notebook-common.ts +22 -181
|
@@ -21,7 +21,9 @@
|
|
|
21
21
|
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
|
|
22
22
|
import { StorageService } from '@theia/core/lib/browser';
|
|
23
23
|
import { NotebookKernel, NotebookTextModelLike, NotebookKernelService } from './notebook-kernel-service';
|
|
24
|
-
import { Disposable } from '@theia/core';
|
|
24
|
+
import { CommandService, Disposable } from '@theia/core';
|
|
25
|
+
import { NotebookModel } from '../view-model/notebook-model';
|
|
26
|
+
import { NotebookCommands } from '../contributions/notebook-actions-contribution';
|
|
25
27
|
|
|
26
28
|
interface KernelsList {
|
|
27
29
|
[viewType: string]: string[];
|
|
@@ -43,6 +45,9 @@ export class NotebookKernelHistoryService implements Disposable {
|
|
|
43
45
|
@inject(NotebookKernelService)
|
|
44
46
|
protected notebookKernelService: NotebookKernelService;
|
|
45
47
|
|
|
48
|
+
@inject(CommandService)
|
|
49
|
+
protected commandService: CommandService;
|
|
50
|
+
|
|
46
51
|
declare serviceBrand: undefined;
|
|
47
52
|
|
|
48
53
|
private static STORAGE_KEY = 'notebook.kernelHistory';
|
|
@@ -68,6 +73,18 @@ export class NotebookKernelHistoryService implements Disposable {
|
|
|
68
73
|
};
|
|
69
74
|
}
|
|
70
75
|
|
|
76
|
+
async resolveSelectedKernel(notebook: NotebookModel): Promise<NotebookKernel | undefined> {
|
|
77
|
+
const alreadySelected = this.getKernels(notebook);
|
|
78
|
+
|
|
79
|
+
if (alreadySelected.selected) {
|
|
80
|
+
return alreadySelected.selected;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
await this.commandService.executeCommand(NotebookCommands.SELECT_KERNEL_COMMAND.id, notebook);
|
|
84
|
+
const { selected } = this.getKernels(notebook);
|
|
85
|
+
return selected;
|
|
86
|
+
}
|
|
87
|
+
|
|
71
88
|
addMostRecentKernel(kernel: NotebookKernel): void {
|
|
72
89
|
const viewType = kernel.viewType;
|
|
73
90
|
const recentKernels = this.mostRecentKernelsMap[viewType] ?? [kernel.id];
|
|
@@ -18,19 +18,18 @@
|
|
|
18
18
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
19
19
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
20
20
|
*--------------------------------------------------------------------------------------------*/
|
|
21
|
-
import { ArrayUtils,
|
|
21
|
+
import { ArrayUtils, CommandService, DisposableCollection, Event, nls, QuickInputButton, QuickInputService, QuickPickInput, QuickPickItem, URI, } from '@theia/core';
|
|
22
22
|
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
23
23
|
import { NotebookKernelService, NotebookKernel, NotebookKernelMatchResult, SourceCommand } from './notebook-kernel-service';
|
|
24
24
|
import { NotebookModel } from '../view-model/notebook-model';
|
|
25
25
|
import { NotebookEditorWidget } from '../notebook-editor-widget';
|
|
26
26
|
import { codicon, OpenerService } from '@theia/core/lib/browser';
|
|
27
27
|
import { NotebookKernelHistoryService } from './notebook-kernel-history-service';
|
|
28
|
+
import { NotebookCommand, NotebookModelResource } from '../../common';
|
|
28
29
|
import debounce = require('@theia/core/shared/lodash.debounce');
|
|
29
30
|
|
|
30
31
|
export const JUPYTER_EXTENSION_ID = 'ms-toolsai.jupyter';
|
|
31
32
|
|
|
32
|
-
export const NotebookKernelQuickPickService = Symbol('NotebookKernelQuickPickService');
|
|
33
|
-
|
|
34
33
|
type KernelPick = QuickPickItem & { kernel: NotebookKernel };
|
|
35
34
|
function isKernelPick(item: QuickPickInput<QuickPickItem>): item is KernelPick {
|
|
36
35
|
return 'kernel' in item;
|
|
@@ -45,7 +44,7 @@ function isSourcePick(item: QuickPickInput<QuickPickItem>): item is SourcePick {
|
|
|
45
44
|
}
|
|
46
45
|
type InstallExtensionPick = QuickPickItem & { extensionIds: string[] };
|
|
47
46
|
|
|
48
|
-
type KernelSourceQuickPickItem = QuickPickItem & { command:
|
|
47
|
+
type KernelSourceQuickPickItem = QuickPickItem & { command: NotebookCommand; documentation?: string };
|
|
49
48
|
function isKernelSourceQuickPickItem(item: QuickPickItem): item is KernelSourceQuickPickItem {
|
|
50
49
|
return 'command' in item;
|
|
51
50
|
}
|
|
@@ -82,7 +81,7 @@ function toKernelQuickPick(kernel: NotebookKernel, selected: NotebookKernel | un
|
|
|
82
81
|
}
|
|
83
82
|
|
|
84
83
|
@injectable()
|
|
85
|
-
export
|
|
84
|
+
export class NotebookKernelQuickPickService {
|
|
86
85
|
|
|
87
86
|
@inject(NotebookKernelService)
|
|
88
87
|
protected readonly notebookKernelService: NotebookKernelService;
|
|
@@ -91,6 +90,12 @@ export abstract class NotebookKernelQuickPickServiceImpl {
|
|
|
91
90
|
@inject(CommandService)
|
|
92
91
|
protected readonly commandService: CommandService;
|
|
93
92
|
|
|
93
|
+
@inject(OpenerService)
|
|
94
|
+
protected openerService: OpenerService;
|
|
95
|
+
|
|
96
|
+
@inject(NotebookKernelHistoryService)
|
|
97
|
+
protected notebookKernelHistoryService: NotebookKernelHistoryService;
|
|
98
|
+
|
|
94
99
|
async showQuickPick(editor: NotebookModel, wantedId?: string, skipAutoRun?: boolean): Promise<boolean> {
|
|
95
100
|
const notebook = editor;
|
|
96
101
|
const matchResult = this.getMatchingResult(notebook);
|
|
@@ -200,40 +205,6 @@ export abstract class NotebookKernelQuickPickServiceImpl {
|
|
|
200
205
|
return false;
|
|
201
206
|
}
|
|
202
207
|
|
|
203
|
-
protected getMatchingResult(notebook: NotebookModel): NotebookKernelMatchResult {
|
|
204
|
-
return this.notebookKernelService.getMatchingKernel(notebook);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
protected abstract getKernelPickerQuickPickItems(matchResult: NotebookKernelMatchResult): QuickPickInput<KernelQuickPickItem>[];
|
|
208
|
-
|
|
209
|
-
protected async handleQuickPick(editor: NotebookModel, pick: KernelQuickPickItem, quickPickItems: KernelQuickPickItem[]): Promise<boolean> {
|
|
210
|
-
if (isKernelPick(pick)) {
|
|
211
|
-
const newKernel = pick.kernel;
|
|
212
|
-
this.selectKernel(editor, newKernel);
|
|
213
|
-
return true;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
if (isSourcePick(pick)) {
|
|
217
|
-
// selected explicitly, it should trigger the execution?
|
|
218
|
-
pick.action.run(this.commandService);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
return true;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
protected selectKernel(notebook: NotebookModel, kernel: NotebookKernel): void {
|
|
225
|
-
this.notebookKernelService.selectKernelForNotebook(kernel, notebook);
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
@injectable()
|
|
229
|
-
export class KernelPickerMRUStrategy extends NotebookKernelQuickPickServiceImpl {
|
|
230
|
-
|
|
231
|
-
@inject(OpenerService)
|
|
232
|
-
protected openerService: OpenerService;
|
|
233
|
-
|
|
234
|
-
@inject(NotebookKernelHistoryService)
|
|
235
|
-
protected notebookKernelHistoryService: NotebookKernelHistoryService;
|
|
236
|
-
|
|
237
208
|
protected getKernelPickerQuickPickItems(matchResult: NotebookKernelMatchResult): QuickPickInput<KernelQuickPickItem>[] {
|
|
238
209
|
const quickPickItems: QuickPickInput<KernelQuickPickItem>[] = [];
|
|
239
210
|
|
|
@@ -266,17 +237,17 @@ export class KernelPickerMRUStrategy extends NotebookKernelQuickPickServiceImpl
|
|
|
266
237
|
return quickPickItems;
|
|
267
238
|
}
|
|
268
239
|
|
|
269
|
-
protected
|
|
240
|
+
protected selectKernel(notebook: NotebookModel, kernel: NotebookKernel): void {
|
|
270
241
|
const currentInfo = this.notebookKernelService.getMatchingKernel(notebook);
|
|
271
242
|
if (currentInfo.selected) {
|
|
272
243
|
// there is already a selected kernel
|
|
273
244
|
this.notebookKernelHistoryService.addMostRecentKernel(currentInfo.selected);
|
|
274
245
|
}
|
|
275
|
-
|
|
246
|
+
this.notebookKernelService.selectKernelForNotebook(kernel, notebook);
|
|
276
247
|
this.notebookKernelHistoryService.addMostRecentKernel(kernel);
|
|
277
248
|
}
|
|
278
249
|
|
|
279
|
-
protected
|
|
250
|
+
protected getMatchingResult(notebook: NotebookModel): NotebookKernelMatchResult {
|
|
280
251
|
const { selected, all } = this.notebookKernelHistoryService.getKernels(notebook);
|
|
281
252
|
const matchingResult = this.notebookKernelService.getMatchingKernel(notebook);
|
|
282
253
|
return {
|
|
@@ -287,12 +258,23 @@ export class KernelPickerMRUStrategy extends NotebookKernelQuickPickServiceImpl
|
|
|
287
258
|
};
|
|
288
259
|
}
|
|
289
260
|
|
|
290
|
-
protected
|
|
261
|
+
protected async handleQuickPick(editor: NotebookModel, pick: KernelQuickPickItem, items: KernelQuickPickItem[]): Promise<boolean> {
|
|
291
262
|
if (pick.id === 'selectAnother') {
|
|
292
263
|
return this.displaySelectAnotherQuickPick(editor, items.length === 1 && items[0] === pick);
|
|
293
264
|
}
|
|
294
265
|
|
|
295
|
-
|
|
266
|
+
if (isKernelPick(pick)) {
|
|
267
|
+
const newKernel = pick.kernel;
|
|
268
|
+
this.selectKernel(editor, newKernel);
|
|
269
|
+
return true;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
if (isSourcePick(pick)) {
|
|
273
|
+
// selected explicitly, it should trigger the execution?
|
|
274
|
+
pick.action.run(this.commandService);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return true;
|
|
296
278
|
}
|
|
297
279
|
|
|
298
280
|
private async displaySelectAnotherQuickPick(editor: NotebookModel, kernelListEmpty: boolean): Promise<boolean> {
|
|
@@ -488,10 +470,8 @@ export class KernelPickerMRUStrategy extends NotebookKernelQuickPickServiceImpl
|
|
|
488
470
|
quickPick.show();
|
|
489
471
|
}
|
|
490
472
|
|
|
491
|
-
private async executeCommand<T>(notebook: NotebookModel, command:
|
|
492
|
-
const
|
|
493
|
-
|
|
494
|
-
return this.commandService.executeCommand(id, { uri: notebook.uri });
|
|
495
|
-
|
|
473
|
+
private async executeCommand<T>(notebook: NotebookModel, command: NotebookCommand): Promise<T | undefined | void> {
|
|
474
|
+
const args = (command.arguments || []).concat([NotebookModelResource.create(notebook.uri)]);
|
|
475
|
+
return this.commandService.executeCommand(command.id, ...args);
|
|
496
476
|
}
|
|
497
477
|
}
|
|
@@ -135,22 +135,31 @@ export class NotebookService implements Disposable {
|
|
|
135
135
|
if (this.notebookProviders.has(type)) {
|
|
136
136
|
return this.notebookProviders.get(type);
|
|
137
137
|
}
|
|
138
|
-
await Promise.all(this.willUseNotebookSerializerEmitter.fire(type));
|
|
139
138
|
const deferred = new Deferred<NotebookProviderInfo | undefined>();
|
|
140
139
|
// 20 seconds of timeout
|
|
141
140
|
const timeoutDuration = 20_000;
|
|
142
|
-
|
|
141
|
+
|
|
142
|
+
// Must declare these variables where they can be captured by the closure
|
|
143
|
+
let disposable: Disposable;
|
|
144
|
+
// eslint-disable-next-line
|
|
145
|
+
let timeout: ReturnType<typeof setTimeout>;
|
|
146
|
+
|
|
147
|
+
// eslint-disable-next-line
|
|
148
|
+
disposable = this.onDidRegisterNotebookSerializer(viewType => {
|
|
143
149
|
if (viewType === type) {
|
|
144
150
|
clearTimeout(timeout);
|
|
145
151
|
disposable.dispose();
|
|
146
152
|
deferred.resolve(this.notebookProviders.get(type));
|
|
147
153
|
}
|
|
148
154
|
});
|
|
149
|
-
|
|
155
|
+
timeout = setTimeout(() => {
|
|
150
156
|
clearTimeout(timeout);
|
|
151
157
|
disposable.dispose();
|
|
152
|
-
deferred.reject();
|
|
158
|
+
deferred.reject(new Error(`Timed out while waiting for notebook serializer for type ${type} to be registered`));
|
|
153
159
|
}, timeoutDuration);
|
|
160
|
+
|
|
161
|
+
await Promise.all(this.willUseNotebookSerializerEmitter.fire(type));
|
|
162
|
+
|
|
154
163
|
return deferred.promise;
|
|
155
164
|
}
|
|
156
165
|
|
|
@@ -77,13 +77,12 @@ export class CellEditor extends React.Component<CellEditorProps, {}> {
|
|
|
77
77
|
}));
|
|
78
78
|
this.toDispose.push(this.editor.onDocumentContentChanged(e => {
|
|
79
79
|
notebookModel.cellDirtyChanged(cell, true);
|
|
80
|
-
cell.source = e.document.getText();
|
|
81
80
|
}));
|
|
82
81
|
}
|
|
83
82
|
}
|
|
84
83
|
|
|
85
|
-
protected
|
|
86
|
-
this.container = component;
|
|
84
|
+
protected setContainer(component: HTMLDivElement | null): void {
|
|
85
|
+
this.container = component ?? undefined;
|
|
87
86
|
};
|
|
88
87
|
|
|
89
88
|
protected handleResize = () => {
|
|
@@ -91,7 +90,10 @@ export class CellEditor extends React.Component<CellEditorProps, {}> {
|
|
|
91
90
|
};
|
|
92
91
|
|
|
93
92
|
override render(): React.ReactNode {
|
|
94
|
-
return <div className='theia-notebook-cell-editor' onResize={this.handleResize} id={this.props.cell.uri.toString()}
|
|
95
|
-
|
|
93
|
+
return <div className='theia-notebook-cell-editor' onResize={this.handleResize} id={this.props.cell.uri.toString()}
|
|
94
|
+
ref={container => this.setContainer(container)}>
|
|
95
|
+
|
|
96
|
+
</div>;
|
|
97
|
+
}
|
|
96
98
|
|
|
97
99
|
}
|
|
@@ -47,7 +47,11 @@ export class NotebookCellListView extends React.Component<CellListProps, Noteboo
|
|
|
47
47
|
super(props);
|
|
48
48
|
this.state = { selectedCell: undefined, dragOverIndicator: undefined };
|
|
49
49
|
this.toDispose.push(props.notebookModel.onDidAddOrRemoveCell(e => {
|
|
50
|
-
|
|
50
|
+
if (e.newCellIds && e.newCellIds.length > 0) {
|
|
51
|
+
this.setState({ ...this.state, selectedCell: this.props.notebookModel.cells.find(model => model.handle === e.newCellIds![e.newCellIds!.length - 1]) });
|
|
52
|
+
} else {
|
|
53
|
+
this.setState({ ...this.state, selectedCell: this.props.notebookModel.cells.find(cell => cell === this.state.selectedCell)});
|
|
54
|
+
}
|
|
51
55
|
}));
|
|
52
56
|
}
|
|
53
57
|
|
|
@@ -101,7 +105,8 @@ export class NotebookCellListView extends React.Component<CellListProps, Noteboo
|
|
|
101
105
|
|
|
102
106
|
protected onDragStart(event: React.DragEvent<HTMLLIElement>, index: number): void {
|
|
103
107
|
event.stopPropagation();
|
|
104
|
-
event.dataTransfer.setData('text/notebook-cell-index', index.toString());
|
|
108
|
+
event.dataTransfer.setData('text/theia-notebook-cell-index', index.toString());
|
|
109
|
+
event.dataTransfer.setData('text/plain', this.props.notebookModel.cells[index].source);
|
|
105
110
|
}
|
|
106
111
|
|
|
107
112
|
protected onDragOver(event: React.DragEvent<HTMLLIElement>, cell: NotebookCellModel, position?: 'top' | 'bottom'): void {
|
|
@@ -112,7 +117,7 @@ export class NotebookCellListView extends React.Component<CellListProps, Noteboo
|
|
|
112
117
|
}
|
|
113
118
|
|
|
114
119
|
protected onDrop(event: React.DragEvent<HTMLLIElement>, dropElementIndex: number): void {
|
|
115
|
-
const index = parseInt(event.dataTransfer.getData('text/notebook-cell-index'));
|
|
120
|
+
const index = parseInt(event.dataTransfer.getData('text/theia-notebook-cell-index'));
|
|
116
121
|
const isTargetBelow = index < dropElementIndex;
|
|
117
122
|
let newIdx = this.state.dragOverIndicator?.position === 'top' ? dropElementIndex : dropElementIndex + 1;
|
|
118
123
|
newIdx = isTargetBelow ? newIdx - 1 : newIdx;
|
|
@@ -29,6 +29,7 @@ export interface NotebookCellToolbarItem {
|
|
|
29
29
|
icon?: string;
|
|
30
30
|
label?: string;
|
|
31
31
|
onClick: (e: React.MouseEvent) => void;
|
|
32
|
+
contextKeys?: Set<string>
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
@injectable()
|
|
@@ -85,7 +86,8 @@ export class NotebookCellToolbarFactory {
|
|
|
85
86
|
includeAnchorArg: false,
|
|
86
87
|
args: [notebookModel, cell, output]
|
|
87
88
|
}) :
|
|
88
|
-
() => this.commandRegistry.executeCommand(menuNode.command!, notebookModel, cell, output)
|
|
89
|
+
() => this.commandRegistry.executeCommand(menuNode.command!, notebookModel, cell, output),
|
|
90
|
+
contextKeys: menuNode.when ? this.contextKeyService.parseKeys(menuNode.when) : undefined
|
|
89
91
|
};
|
|
90
92
|
}
|
|
91
93
|
}
|
|
@@ -17,24 +17,27 @@ import * as React from '@theia/core/shared/react';
|
|
|
17
17
|
import { ACTION_ITEM } from '@theia/core/lib/browser';
|
|
18
18
|
import { NotebookCellToolbarItem } from './notebook-cell-toolbar-factory';
|
|
19
19
|
import { DisposableCollection, Event } from '@theia/core';
|
|
20
|
+
import { ContextKeyChangeEvent } from '@theia/core/lib/browser/context-key-service';
|
|
20
21
|
|
|
21
22
|
export interface NotebookCellToolbarProps {
|
|
22
23
|
getMenuItems: () => NotebookCellToolbarItem[];
|
|
23
|
-
onContextKeysChanged: Event<
|
|
24
|
+
onContextKeysChanged: Event<ContextKeyChangeEvent>;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
interface NotebookCellToolbarState {
|
|
27
28
|
inlineItems: NotebookCellToolbarItem[];
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
abstract class
|
|
31
|
+
abstract class NotebookCellActionBar extends React.Component<NotebookCellToolbarProps, NotebookCellToolbarState> {
|
|
31
32
|
|
|
32
33
|
protected toDispose = new DisposableCollection();
|
|
33
34
|
|
|
34
35
|
constructor(props: NotebookCellToolbarProps) {
|
|
35
36
|
super(props);
|
|
36
37
|
this.toDispose.push(props.onContextKeysChanged(e => {
|
|
37
|
-
this.
|
|
38
|
+
if (this.props.getMenuItems().some(item => item.contextKeys ? e.affects(item.contextKeys) : false)) {
|
|
39
|
+
this.setState({ inlineItems: this.props.getMenuItems() });
|
|
40
|
+
}
|
|
38
41
|
}));
|
|
39
42
|
this.state = { inlineItems: this.props.getMenuItems() };
|
|
40
43
|
}
|
|
@@ -49,7 +52,7 @@ abstract class NotebookCellActionItems extends React.Component<NotebookCellToolb
|
|
|
49
52
|
|
|
50
53
|
}
|
|
51
54
|
|
|
52
|
-
export class NotebookCellToolbar extends
|
|
55
|
+
export class NotebookCellToolbar extends NotebookCellActionBar {
|
|
53
56
|
|
|
54
57
|
override render(): React.ReactNode {
|
|
55
58
|
return <div className='theia-notebook-cell-toolbar'>
|
|
@@ -59,7 +62,7 @@ export class NotebookCellToolbar extends NotebookCellActionItems {
|
|
|
59
62
|
|
|
60
63
|
}
|
|
61
64
|
|
|
62
|
-
export class NotebookCellSidebar extends
|
|
65
|
+
export class NotebookCellSidebar extends NotebookCellActionBar {
|
|
63
66
|
|
|
64
67
|
override render(): React.ReactNode {
|
|
65
68
|
return <div className='theia-notebook-cell-sidebar'>
|
|
@@ -66,6 +66,15 @@ export class NotebookMainToolbar extends React.Component<NotebookMainToolbarProp
|
|
|
66
66
|
this.setState({ selectedKernelLabel: props.notebookKernelService.getSelectedOrSuggestedKernel(props.notebookModel)?.label });
|
|
67
67
|
}
|
|
68
68
|
}));
|
|
69
|
+
|
|
70
|
+
// TODO maybe we need a mechanism to check for changes in the menu to update this toolbar
|
|
71
|
+
const contextKeys = new Set<string>();
|
|
72
|
+
this.getMenuItems().filter(item => item.when).forEach(item => props.contextKeyService.parseKeys(item.when!)?.forEach(key => contextKeys.add(key)));
|
|
73
|
+
props.contextKeyService.onDidChange(e => {
|
|
74
|
+
if (e.affects(contextKeys)) {
|
|
75
|
+
this.forceUpdate();
|
|
76
|
+
}
|
|
77
|
+
});
|
|
69
78
|
}
|
|
70
79
|
|
|
71
80
|
override componentWillUnmount(): void {
|
|
@@ -20,12 +20,14 @@
|
|
|
20
20
|
|
|
21
21
|
import { Disposable, DisposableCollection, Emitter, Event, URI } from '@theia/core';
|
|
22
22
|
import { inject, injectable, interfaces, postConstruct } from '@theia/core/shared/inversify';
|
|
23
|
+
import { ContextKeyChangeEvent } from '@theia/core/lib/browser/context-key-service';
|
|
23
24
|
import { MonacoEditorModel } from '@theia/monaco/lib/browser/monaco-editor-model';
|
|
24
25
|
import { MonacoTextModelService } from '@theia/monaco/lib/browser/monaco-text-model-service';
|
|
25
26
|
import {
|
|
26
|
-
|
|
27
|
-
NotebookCellMetadata,
|
|
27
|
+
CellKind, NotebookCellCollapseState, NotebookCellInternalMetadata,
|
|
28
|
+
NotebookCellMetadata, CellOutput, CellData, CellOutputItem
|
|
28
29
|
} from '../../common';
|
|
30
|
+
import { NotebookCellOutputsSplice } from '../notebook-types';
|
|
29
31
|
import { NotebookCellOutputModel } from './notebook-cell-output-model';
|
|
30
32
|
|
|
31
33
|
export const NotebookCellModelFactory = Symbol('NotebookModelFactory');
|
|
@@ -47,7 +49,28 @@ const NotebookCellContextManager = Symbol('NotebookCellContextManager');
|
|
|
47
49
|
interface NotebookCellContextManager {
|
|
48
50
|
updateCellContext(cell: NotebookCellModel, context: HTMLElement): void;
|
|
49
51
|
dispose(): void;
|
|
50
|
-
onDidChangeContext: Event<
|
|
52
|
+
onDidChangeContext: Event<ContextKeyChangeEvent>;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface CellInternalMetadataChangedEvent {
|
|
56
|
+
readonly lastRunSuccessChanged?: boolean;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface NotebookCell {
|
|
60
|
+
readonly uri: URI;
|
|
61
|
+
handle: number;
|
|
62
|
+
language: string;
|
|
63
|
+
cellKind: CellKind;
|
|
64
|
+
outputs: CellOutput[];
|
|
65
|
+
metadata: NotebookCellMetadata;
|
|
66
|
+
internalMetadata: NotebookCellInternalMetadata;
|
|
67
|
+
text: string;
|
|
68
|
+
onDidChangeOutputs?: Event<NotebookCellOutputsSplice>;
|
|
69
|
+
onDidChangeOutputItems?: Event<CellOutput>;
|
|
70
|
+
onDidChangeLanguage: Event<string>;
|
|
71
|
+
onDidChangeMetadata: Event<void>;
|
|
72
|
+
onDidChangeInternalMetadata: Event<CellInternalMetadataChangedEvent>;
|
|
73
|
+
|
|
51
74
|
}
|
|
52
75
|
|
|
53
76
|
const NotebookCellModelProps = Symbol('NotebookModelProps');
|
|
@@ -144,6 +167,7 @@ export class NotebookCellModel implements NotebookCell, Disposable {
|
|
|
144
167
|
}
|
|
145
168
|
set source(source: string) {
|
|
146
169
|
this.props.source = source;
|
|
170
|
+
this.textModel?.textEditorModel.setValue(source);
|
|
147
171
|
}
|
|
148
172
|
get language(): string {
|
|
149
173
|
return this.props.language;
|
|
@@ -274,6 +298,9 @@ export class NotebookCellModel implements NotebookCell, Disposable {
|
|
|
274
298
|
|
|
275
299
|
const ref = await this.textModelService.createModelReference(this.uri);
|
|
276
300
|
this.textModel = ref.object;
|
|
301
|
+
this.textModel.onDidChangeContent(e => {
|
|
302
|
+
this.props.source = e.model.getText();
|
|
303
|
+
});
|
|
277
304
|
return ref.object;
|
|
278
305
|
}
|
|
279
306
|
}
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
17
|
import { Disposable, Emitter } from '@theia/core';
|
|
18
|
-
import { BinaryBuffer } from '@theia/core/lib/common/buffer';
|
|
19
18
|
import { CellOutput, CellOutputItem, isTextStreamMime } from '../../common';
|
|
19
|
+
import { compressOutputItemStreams } from '../notebook-output-utils';
|
|
20
20
|
|
|
21
21
|
export class NotebookCellOutputModel implements Disposable {
|
|
22
22
|
|
|
@@ -73,10 +73,10 @@ export class NotebookCellOutputModel implements Disposable {
|
|
|
73
73
|
if (this.outputs.length > 1 && this.outputs.every(item => isTextStreamMime(item.mime))) {
|
|
74
74
|
// Look for the mimes in the items, and keep track of their order.
|
|
75
75
|
// Merge the streams into one output item, per mime type.
|
|
76
|
-
const mimeOutputs = new Map<string,
|
|
76
|
+
const mimeOutputs = new Map<string, Uint8Array[]>();
|
|
77
77
|
const mimeTypes: string[] = [];
|
|
78
78
|
this.outputs.forEach(item => {
|
|
79
|
-
let items:
|
|
79
|
+
let items: Uint8Array[];
|
|
80
80
|
if (mimeOutputs.has(item.mime)) {
|
|
81
81
|
items = mimeOutputs.get(item.mime)!;
|
|
82
82
|
} else {
|
|
@@ -84,13 +84,14 @@ export class NotebookCellOutputModel implements Disposable {
|
|
|
84
84
|
mimeOutputs.set(item.mime, items);
|
|
85
85
|
mimeTypes.push(item.mime);
|
|
86
86
|
}
|
|
87
|
-
items.push(item.data);
|
|
87
|
+
items.push(item.data.buffer);
|
|
88
88
|
});
|
|
89
89
|
this.outputs.length = 0;
|
|
90
90
|
mimeTypes.forEach(mime => {
|
|
91
|
+
const compressionResult = compressOutputItemStreams(mimeOutputs.get(mime)!);
|
|
91
92
|
this.outputs.push({
|
|
92
93
|
mime,
|
|
93
|
-
data:
|
|
94
|
+
data: compressionResult.data
|
|
94
95
|
});
|
|
95
96
|
});
|
|
96
97
|
}
|