@theia/notebook 1.50.0 → 1.51.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.js +2 -2
- package/lib/browser/contributions/notebook-actions-contribution.js.map +1 -1
- package/lib/browser/contributions/notebook-preferences.d.ts +9 -1
- package/lib/browser/contributions/notebook-preferences.d.ts.map +1 -1
- package/lib/browser/contributions/notebook-preferences.js +53 -3
- package/lib/browser/contributions/notebook-preferences.js.map +1 -1
- package/lib/browser/notebook-editor-widget.d.ts.map +1 -1
- package/lib/browser/notebook-editor-widget.js +2 -1
- package/lib/browser/notebook-editor-widget.js.map +1 -1
- package/lib/browser/notebook-frontend-module.d.ts.map +1 -1
- package/lib/browser/notebook-frontend-module.js +2 -0
- package/lib/browser/notebook-frontend-module.js.map +1 -1
- package/lib/browser/service/notebook-editor-widget-service.d.ts +5 -4
- package/lib/browser/service/notebook-editor-widget-service.d.ts.map +1 -1
- package/lib/browser/service/notebook-editor-widget-service.js +3 -0
- package/lib/browser/service/notebook-editor-widget-service.js.map +1 -1
- package/lib/browser/service/notebook-execution-service.d.ts +2 -2
- package/lib/browser/service/notebook-execution-service.d.ts.map +1 -1
- package/lib/browser/service/notebook-execution-service.js.map +1 -1
- package/lib/browser/service/notebook-execution-state-service.d.ts +13 -13
- 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-quick-pick-service.d.ts +5 -5
- package/lib/browser/service/notebook-kernel-quick-pick-service.d.ts.map +1 -1
- package/lib/browser/service/notebook-kernel-quick-pick-service.js.map +1 -1
- package/lib/browser/service/notebook-kernel-service.d.ts +4 -4
- package/lib/browser/service/notebook-kernel-service.d.ts.map +1 -1
- package/lib/browser/service/notebook-kernel-service.js.map +1 -1
- package/lib/browser/service/notebook-options.d.ts +29 -0
- package/lib/browser/service/notebook-options.d.ts.map +1 -0
- package/lib/browser/service/notebook-options.js +129 -0
- package/lib/browser/service/notebook-options.js.map +1 -0
- package/lib/browser/service/notebook-renderer-messaging-service.d.ts +8 -6
- package/lib/browser/service/notebook-renderer-messaging-service.d.ts.map +1 -1
- package/lib/browser/service/notebook-renderer-messaging-service.js.map +1 -1
- package/lib/browser/view/notebook-cell-editor.d.ts.map +1 -1
- package/lib/browser/view/notebook-cell-editor.js +2 -1
- package/lib/browser/view/notebook-cell-editor.js.map +1 -1
- package/lib/browser/view/notebook-cell-list-view.d.ts +1 -1
- package/lib/browser/view/notebook-cell-list-view.d.ts.map +1 -1
- package/lib/browser/view/notebook-cell-list-view.js +10 -9
- package/lib/browser/view/notebook-cell-list-view.js.map +1 -1
- package/lib/browser/view/notebook-code-cell-view.d.ts +5 -4
- package/lib/browser/view/notebook-code-cell-view.d.ts.map +1 -1
- package/lib/browser/view/notebook-code-cell-view.js +43 -19
- package/lib/browser/view/notebook-code-cell-view.js.map +1 -1
- package/lib/browser/view/notebook-markdown-cell-view.d.ts.map +1 -1
- package/lib/browser/view/notebook-markdown-cell-view.js +5 -2
- package/lib/browser/view/notebook-markdown-cell-view.js.map +1 -1
- package/lib/browser/view-model/notebook-cell-model.js +3 -3
- package/lib/browser/view-model/notebook-cell-model.js.map +1 -1
- package/lib/browser/view-model/notebook-cell-output-model.d.ts +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.map +1 -1
- package/lib/browser/view-model/notebook-model.d.ts +2 -0
- package/lib/browser/view-model/notebook-model.d.ts.map +1 -1
- package/lib/browser/view-model/notebook-model.js +6 -3
- package/lib/browser/view-model/notebook-model.js.map +1 -1
- package/package.json +8 -8
- package/src/browser/contributions/notebook-actions-contribution.ts +2 -2
- package/src/browser/contributions/notebook-preferences.ts +54 -2
- package/src/browser/notebook-editor-widget.tsx +3 -1
- package/src/browser/notebook-frontend-module.ts +2 -0
- package/src/browser/service/notebook-editor-widget-service.ts +7 -4
- package/src/browser/service/notebook-execution-service.ts +2 -2
- package/src/browser/service/notebook-execution-state-service.ts +12 -12
- package/src/browser/service/notebook-kernel-quick-pick-service.ts +5 -5
- package/src/browser/service/notebook-kernel-service.ts +4 -4
- package/src/browser/service/notebook-options.ts +154 -0
- package/src/browser/service/notebook-renderer-messaging-service.ts +6 -6
- package/src/browser/style/index.css +11 -2
- package/src/browser/view/notebook-cell-editor.tsx +3 -1
- package/src/browser/view/notebook-cell-list-view.tsx +10 -9
- package/src/browser/view/notebook-code-cell-view.tsx +40 -20
- package/src/browser/view/notebook-markdown-cell-view.tsx +4 -2
- package/src/browser/view-model/notebook-cell-model.ts +4 -4
- package/src/browser/view-model/notebook-cell-output-model.ts +1 -1
- package/src/browser/view-model/notebook-model.ts +7 -3
|
@@ -35,14 +35,14 @@ export class NotebookEditorWidgetService {
|
|
|
35
35
|
@inject(ContextKeyService)
|
|
36
36
|
protected contextKeyService: ContextKeyService;
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
protected readonly notebookEditors = new Map<string, NotebookEditorWidget>();
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
protected readonly onNotebookEditorAddEmitter = new Emitter<NotebookEditorWidget>();
|
|
41
|
+
protected readonly onNotebookEditorRemoveEmitter = new Emitter<NotebookEditorWidget>();
|
|
42
42
|
readonly onDidAddNotebookEditor = this.onNotebookEditorAddEmitter.event;
|
|
43
43
|
readonly onDidRemoveNotebookEditor = this.onNotebookEditorRemoveEmitter.event;
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
protected readonly onDidChangeFocusedEditorEmitter = new Emitter<NotebookEditorWidget | undefined>();
|
|
46
46
|
readonly onDidChangeFocusedEditor = this.onDidChangeFocusedEditorEmitter.event;
|
|
47
47
|
|
|
48
48
|
focusedEditor?: NotebookEditorWidget = undefined;
|
|
@@ -62,6 +62,9 @@ export class NotebookEditorWidgetService {
|
|
|
62
62
|
}
|
|
63
63
|
this.notebookEditors.set(editor.id, editor);
|
|
64
64
|
this.onNotebookEditorAddEmitter.fire(editor);
|
|
65
|
+
if (editor.isVisible) {
|
|
66
|
+
this.notebookEditorFocusChanged(editor, true);
|
|
67
|
+
}
|
|
65
68
|
}
|
|
66
69
|
|
|
67
70
|
removeNotebookEditor(editor: NotebookEditorWidget): void {
|
|
@@ -50,7 +50,7 @@ export class NotebookExecutionService {
|
|
|
50
50
|
@inject(NotebookKernelQuickPickService)
|
|
51
51
|
protected notebookKernelQuickPickService: NotebookKernelQuickPickService;
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
protected readonly cellExecutionParticipants = new Set<CellExecutionParticipant>();
|
|
54
54
|
|
|
55
55
|
async executeNotebookCells(notebook: NotebookModel, cells: Iterable<NotebookCellModel>): Promise<void> {
|
|
56
56
|
const cellsArr = Array.from(cells)
|
|
@@ -117,7 +117,7 @@ export class NotebookExecutionService {
|
|
|
117
117
|
return Disposable.create(() => this.cellExecutionParticipants.delete(participant));
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
protected async runExecutionParticipants(executions: CellExecution[]): Promise<void> {
|
|
121
121
|
for (const participant of this.cellExecutionParticipants) {
|
|
122
122
|
await participant.onWillExecuteCell(executions);
|
|
123
123
|
}
|
|
@@ -69,10 +69,10 @@ export class NotebookExecutionStateService implements Disposable {
|
|
|
69
69
|
|
|
70
70
|
protected readonly executions = new Map<string, Map<number, CellExecution>>();
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
protected readonly onDidChangeExecutionEmitter = new Emitter<CellExecutionStateChangedEvent>();
|
|
73
73
|
onDidChangeExecution = this.onDidChangeExecutionEmitter.event;
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
protected readonly onDidChangeLastRunFailStateEmitter = new Emitter<NotebookFailStateChangedEvent>();
|
|
76
76
|
onDidChangeLastRunFailState = this.onDidChangeLastRunFailStateEmitter.event;
|
|
77
77
|
|
|
78
78
|
getOrCreateCellExecution(notebookUri: URI, cellHandle: number): CellExecution {
|
|
@@ -98,7 +98,7 @@ export class NotebookExecutionStateService implements Disposable {
|
|
|
98
98
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
protected createNotebookCellExecution(notebook: NotebookModel, cellHandle: number): CellExecution {
|
|
102
102
|
const notebookUri = notebook.uri;
|
|
103
103
|
const execution = new CellExecution(cellHandle, notebook);
|
|
104
104
|
execution.toDispose.push(execution.onDidUpdate(() => this.onDidChangeExecutionEmitter.fire(new CellExecutionStateChangedEvent(notebookUri, cellHandle, execution))));
|
|
@@ -107,7 +107,7 @@ export class NotebookExecutionStateService implements Disposable {
|
|
|
107
107
|
return execution;
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
|
|
110
|
+
protected onCellExecutionDidComplete(notebookUri: URI, cellHandle: number, exe: CellExecution, lastRunSuccess?: boolean): void {
|
|
111
111
|
const notebookExecutions = this.executions.get(notebookUri.toString())?.get(cellHandle);
|
|
112
112
|
if (!notebookExecutions) {
|
|
113
113
|
throw new Error('Notebook Cell Execution not found while trying to complete it');
|
|
@@ -138,15 +138,15 @@ export class NotebookExecutionStateService implements Disposable {
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
export class CellExecution implements Disposable {
|
|
141
|
-
|
|
141
|
+
protected readonly onDidUpdateEmitter = new Emitter<void>();
|
|
142
142
|
readonly onDidUpdate = this.onDidUpdateEmitter.event;
|
|
143
143
|
|
|
144
|
-
|
|
144
|
+
protected readonly onDidCompleteEmitter = new Emitter<boolean | undefined>();
|
|
145
145
|
readonly onDidComplete = this.onDidCompleteEmitter.event;
|
|
146
146
|
|
|
147
147
|
toDispose = new DisposableCollection();
|
|
148
148
|
|
|
149
|
-
|
|
149
|
+
protected _state: NotebookCellExecutionState = NotebookCellExecutionState.Unconfirmed;
|
|
150
150
|
get state(): NotebookCellExecutionState {
|
|
151
151
|
return this._state;
|
|
152
152
|
}
|
|
@@ -155,19 +155,19 @@ export class CellExecution implements Disposable {
|
|
|
155
155
|
return this.notebook.uri;
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
-
|
|
158
|
+
protected _didPause = false;
|
|
159
159
|
get didPause(): boolean {
|
|
160
160
|
return this._didPause;
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
|
|
163
|
+
protected _isPaused = false;
|
|
164
164
|
get isPaused(): boolean {
|
|
165
165
|
return this._isPaused;
|
|
166
166
|
}
|
|
167
167
|
|
|
168
168
|
constructor(
|
|
169
169
|
readonly cellHandle: number,
|
|
170
|
-
|
|
170
|
+
protected readonly notebook: NotebookModel,
|
|
171
171
|
) {
|
|
172
172
|
console.debug(`CellExecution#ctor ${this.getCellLog()}`);
|
|
173
173
|
}
|
|
@@ -188,7 +188,7 @@ export class CellExecution implements Disposable {
|
|
|
188
188
|
this.applyCellExecutionEditsToNotebook([startExecuteEdit]);
|
|
189
189
|
}
|
|
190
190
|
|
|
191
|
-
|
|
191
|
+
protected getCellLog(): string {
|
|
192
192
|
return `${this.notebookURI.toString()}, ${this.cellHandle}`;
|
|
193
193
|
}
|
|
194
194
|
|
|
@@ -254,7 +254,7 @@ export class CellExecution implements Disposable {
|
|
|
254
254
|
this.toDispose.dispose();
|
|
255
255
|
}
|
|
256
256
|
|
|
257
|
-
|
|
257
|
+
protected applyCellExecutionEditsToNotebook(edits: CellEditOperation[]): void {
|
|
258
258
|
this.notebook.applyEdits(edits, false);
|
|
259
259
|
}
|
|
260
260
|
}
|
|
@@ -277,7 +277,7 @@ export class NotebookKernelQuickPickService {
|
|
|
277
277
|
return true;
|
|
278
278
|
}
|
|
279
279
|
|
|
280
|
-
|
|
280
|
+
protected async displaySelectAnotherQuickPick(editor: NotebookModel, kernelListEmpty: boolean): Promise<boolean> {
|
|
281
281
|
const notebook: NotebookModel = editor;
|
|
282
282
|
const disposables = new DisposableCollection();
|
|
283
283
|
const quickPick = this.quickInputService.createQuickPick<KernelQuickPickItem>();
|
|
@@ -399,11 +399,11 @@ export class NotebookKernelQuickPickService {
|
|
|
399
399
|
return false;
|
|
400
400
|
}
|
|
401
401
|
|
|
402
|
-
|
|
402
|
+
protected isUri(value: string): boolean {
|
|
403
403
|
return /^(?<scheme>\w[\w\d+.-]*):/.test(value);
|
|
404
404
|
}
|
|
405
405
|
|
|
406
|
-
|
|
406
|
+
protected async calculateKernelSources(editor: NotebookModel): Promise<QuickPickInput<KernelQuickPickItem>[]> {
|
|
407
407
|
const notebook: NotebookModel = editor;
|
|
408
408
|
|
|
409
409
|
const actions = await this.notebookKernelService.getKernelSourceActionsFromProviders(notebook);
|
|
@@ -448,7 +448,7 @@ export class NotebookKernelQuickPickService {
|
|
|
448
448
|
return quickPickItems;
|
|
449
449
|
}
|
|
450
450
|
|
|
451
|
-
|
|
451
|
+
protected async selectOneKernel(notebook: NotebookModel, source: string, kernels: NotebookKernel[]): Promise<void> {
|
|
452
452
|
const quickPickItems: QuickPickInput<KernelPick>[] = kernels.map(kernel => toKernelQuickPick(kernel, undefined));
|
|
453
453
|
const quickPick = this.quickInputService.createQuickPick<KernelQuickPickItem>();
|
|
454
454
|
quickPick.items = quickPickItems;
|
|
@@ -472,7 +472,7 @@ export class NotebookKernelQuickPickService {
|
|
|
472
472
|
quickPick.show();
|
|
473
473
|
}
|
|
474
474
|
|
|
475
|
-
|
|
475
|
+
protected async executeCommand<T>(notebook: NotebookModel, command: NotebookCommand): Promise<T | undefined | void> {
|
|
476
476
|
const args = (command.arguments || []).concat([NotebookModelResource.create(notebook.uri)]);
|
|
477
477
|
return this.commandService.executeCommand(command.id, ...args);
|
|
478
478
|
}
|
|
@@ -84,7 +84,7 @@ export interface NotebookTextModelLike { uri: URI; viewType: string }
|
|
|
84
84
|
|
|
85
85
|
class KernelInfo {
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
protected static instanceCounter = 0;
|
|
88
88
|
|
|
89
89
|
score: number;
|
|
90
90
|
readonly kernel: NotebookKernel;
|
|
@@ -130,7 +130,7 @@ export class SourceCommand implements Disposable {
|
|
|
130
130
|
this.onDidChangeStateEmitter.fire();
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
|
|
133
|
+
protected async runCommand(commandService: CommandService): Promise<void> {
|
|
134
134
|
try {
|
|
135
135
|
await commandService.executeCommand(this.command.id, {
|
|
136
136
|
uri: this.model.uri,
|
|
@@ -278,7 +278,7 @@ export class NotebookKernelService {
|
|
|
278
278
|
return this.kernels.get(id)?.kernel;
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
-
|
|
281
|
+
protected static score(kernel: NotebookKernel, notebook: NotebookTextModelLike): number {
|
|
282
282
|
if (kernel.viewType === notebook.viewType) {
|
|
283
283
|
return 10;
|
|
284
284
|
} else if (kernel.viewType === '*') {
|
|
@@ -288,7 +288,7 @@ export class NotebookKernelService {
|
|
|
288
288
|
}
|
|
289
289
|
}
|
|
290
290
|
|
|
291
|
-
|
|
291
|
+
protected tryAutoBindNotebook(notebook: NotebookModel, onlyThisKernel?: NotebookKernel): void {
|
|
292
292
|
|
|
293
293
|
const id = this.notebookBindings[`${notebook.viewType}/${notebook.uri}`];
|
|
294
294
|
if (!id) {
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
|
|
2
|
+
// *****************************************************************************
|
|
3
|
+
// Copyright (C) 2024 TypeFox and others.
|
|
4
|
+
//
|
|
5
|
+
// This program and the accompanying materials are made available under the
|
|
6
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
7
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
8
|
+
//
|
|
9
|
+
// This Source Code may also be made available under the following Secondary
|
|
10
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
11
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
12
|
+
// with the GNU Classpath Exception which is available at
|
|
13
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
14
|
+
//
|
|
15
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
16
|
+
// *****************************************************************************
|
|
17
|
+
|
|
18
|
+
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
|
|
19
|
+
import { PreferenceService } from '@theia/core/lib/browser';
|
|
20
|
+
import { Emitter } from '@theia/core';
|
|
21
|
+
import { NotebookPreferences, notebookPreferenceSchema } from '../contributions/notebook-preferences';
|
|
22
|
+
import { EditorPreferences } from '@theia/editor/lib/browser';
|
|
23
|
+
import { BareFontInfo } from '@theia/monaco-editor-core/esm/vs/editor/common/config/fontInfo';
|
|
24
|
+
import { PixelRatio } from '@theia/monaco-editor-core/esm/vs/base/browser/browser';
|
|
25
|
+
|
|
26
|
+
const notebookOutputOptionsRelevantPreferences = [
|
|
27
|
+
'editor.fontSize',
|
|
28
|
+
'editor.fontFamily',
|
|
29
|
+
NotebookPreferences.NOTEBOOK_LINE_NUMBERS,
|
|
30
|
+
NotebookPreferences.OUTPUT_LINE_HEIGHT,
|
|
31
|
+
NotebookPreferences.OUTPUT_FONT_SIZE,
|
|
32
|
+
NotebookPreferences.OUTPUT_FONT_FAMILY,
|
|
33
|
+
NotebookPreferences.OUTPUT_SCROLLING,
|
|
34
|
+
NotebookPreferences.OUTPUT_WORD_WRAP,
|
|
35
|
+
NotebookPreferences.OUTPUT_LINE_LIMIT
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
export interface NotebookOutputOptions {
|
|
39
|
+
// readonly outputNodePadding: number;
|
|
40
|
+
// readonly outputNodeLeftPadding: number;
|
|
41
|
+
// readonly previewNodePadding: number;
|
|
42
|
+
// readonly markdownLeftMargin: number;
|
|
43
|
+
// readonly leftMargin: number;
|
|
44
|
+
// readonly rightMargin: number;
|
|
45
|
+
// readonly runGutter: number;
|
|
46
|
+
// readonly dragAndDropEnabled: boolean;
|
|
47
|
+
readonly fontSize: number;
|
|
48
|
+
readonly outputFontSize?: number;
|
|
49
|
+
readonly fontFamily: string;
|
|
50
|
+
readonly outputFontFamily?: string;
|
|
51
|
+
// readonly markupFontSize: number;
|
|
52
|
+
// readonly markdownLineHeight: number;
|
|
53
|
+
readonly outputLineHeight: number;
|
|
54
|
+
readonly outputScrolling: boolean;
|
|
55
|
+
readonly outputWordWrap: boolean;
|
|
56
|
+
readonly outputLineLimit: number;
|
|
57
|
+
// readonly outputLinkifyFilePaths: boolean;
|
|
58
|
+
// readonly minimalError: boolean;
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
@injectable()
|
|
63
|
+
export class NotebookOptionsService {
|
|
64
|
+
|
|
65
|
+
@inject(PreferenceService)
|
|
66
|
+
protected readonly preferenceService: PreferenceService;
|
|
67
|
+
|
|
68
|
+
@inject(EditorPreferences)
|
|
69
|
+
protected readonly editorPreferences: EditorPreferences;
|
|
70
|
+
|
|
71
|
+
protected outputOptionsChangedEmitter = new Emitter<NotebookOutputOptions>();
|
|
72
|
+
onDidChangeOutputOptions = this.outputOptionsChangedEmitter.event;
|
|
73
|
+
|
|
74
|
+
protected fontInfo?: BareFontInfo;
|
|
75
|
+
get editorFontInfo(): BareFontInfo {
|
|
76
|
+
return this.getOrCreateMonacoFontInfo();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@postConstruct()
|
|
80
|
+
protected init(): void {
|
|
81
|
+
this.preferenceService.onPreferencesChanged(async preferenceChanges => {
|
|
82
|
+
if (notebookOutputOptionsRelevantPreferences.some(p => p in preferenceChanges)) {
|
|
83
|
+
this.outputOptionsChangedEmitter.fire(this.computeOutputOptions());
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
computeOutputOptions(): NotebookOutputOptions {
|
|
89
|
+
const outputLineHeight = this.getNotebookPreferenceWithDefault<number>(NotebookPreferences.OUTPUT_LINE_HEIGHT);
|
|
90
|
+
|
|
91
|
+
const fontSize = this.preferenceService.get<number>('editor.fontSize')!;
|
|
92
|
+
const outputFontSize = this.getNotebookPreferenceWithDefault<number>(NotebookPreferences.OUTPUT_FONT_SIZE);
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
fontSize,
|
|
96
|
+
outputFontSize: outputFontSize,
|
|
97
|
+
fontFamily: this.preferenceService.get<string>('editor.fontFamily')!,
|
|
98
|
+
outputFontFamily: this.getNotebookPreferenceWithDefault<string>(NotebookPreferences.OUTPUT_FONT_FAMILY),
|
|
99
|
+
outputLineHeight: this.computeOutputLineHeight(outputLineHeight, outputFontSize ?? fontSize),
|
|
100
|
+
outputScrolling: this.getNotebookPreferenceWithDefault<boolean>(NotebookPreferences.OUTPUT_SCROLLING)!,
|
|
101
|
+
outputWordWrap: this.getNotebookPreferenceWithDefault<boolean>(NotebookPreferences.OUTPUT_WORD_WRAP)!,
|
|
102
|
+
outputLineLimit: this.getNotebookPreferenceWithDefault<number>(NotebookPreferences.OUTPUT_LINE_LIMIT)!
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
protected getNotebookPreferenceWithDefault<T>(key: string): T {
|
|
107
|
+
return this.preferenceService.get<T>(key, notebookPreferenceSchema.properties?.[key]?.default as T);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
protected computeOutputLineHeight(lineHeight: number, outputFontSize: number): number {
|
|
111
|
+
const minimumLineHeight = 9;
|
|
112
|
+
|
|
113
|
+
if (lineHeight === 0) {
|
|
114
|
+
// use editor line height
|
|
115
|
+
lineHeight = this.editorFontInfo.lineHeight;
|
|
116
|
+
} else if (lineHeight < minimumLineHeight) {
|
|
117
|
+
// Values too small to be line heights in pixels are in ems.
|
|
118
|
+
let fontSize = outputFontSize;
|
|
119
|
+
if (fontSize === 0) {
|
|
120
|
+
fontSize = this.preferenceService.get<number>('editor.fontSize')!;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
lineHeight = lineHeight * fontSize;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Enforce integer, minimum constraints
|
|
127
|
+
lineHeight = Math.round(lineHeight);
|
|
128
|
+
if (lineHeight < minimumLineHeight) {
|
|
129
|
+
lineHeight = minimumLineHeight;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return lineHeight;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
protected getOrCreateMonacoFontInfo(): BareFontInfo {
|
|
136
|
+
if (!this.fontInfo) {
|
|
137
|
+
this.fontInfo = this.createFontInfo();
|
|
138
|
+
this.editorPreferences.onPreferenceChanged(e => this.fontInfo = this.createFontInfo());
|
|
139
|
+
}
|
|
140
|
+
return this.fontInfo;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
protected createFontInfo(): BareFontInfo {
|
|
144
|
+
return BareFontInfo.createFromRawSettings({
|
|
145
|
+
fontFamily: this.editorPreferences['editor.fontFamily'],
|
|
146
|
+
fontWeight: String(this.editorPreferences['editor.fontWeight']),
|
|
147
|
+
fontSize: this.editorPreferences['editor.fontSize'],
|
|
148
|
+
fontLigatures: this.editorPreferences['editor.fontLigatures'],
|
|
149
|
+
lineHeight: this.editorPreferences['editor.lineHeight'],
|
|
150
|
+
letterSpacing: this.editorPreferences['editor.letterSpacing'],
|
|
151
|
+
}, PixelRatio.value);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
}
|
|
@@ -45,17 +45,17 @@ export interface RendererMessaging extends Disposable {
|
|
|
45
45
|
@injectable()
|
|
46
46
|
export class NotebookRendererMessagingService implements Disposable {
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
protected readonly postMessageEmitter = new Emitter<RendererMessage>();
|
|
49
49
|
readonly onPostMessage = this.postMessageEmitter.event;
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
protected readonly willActivateRendererEmitter = new Emitter<string>();
|
|
52
52
|
readonly onWillActivateRenderer = this.willActivateRendererEmitter.event;
|
|
53
53
|
|
|
54
54
|
@inject(NotebookEditorWidgetService)
|
|
55
|
-
|
|
55
|
+
protected readonly editorWidgetService: NotebookEditorWidgetService;
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
protected readonly activations = new Map<string /* rendererId */, undefined | RendererMessage[]>();
|
|
58
|
+
protected readonly scopedMessaging = new Map<string /* editorId */, RendererMessaging>();
|
|
59
59
|
|
|
60
60
|
receiveMessage(editorId: string | undefined, rendererId: string, message: unknown): Promise<boolean> {
|
|
61
61
|
if (editorId === undefined) {
|
|
@@ -101,7 +101,7 @@ export class NotebookRendererMessagingService implements Disposable {
|
|
|
101
101
|
return messaging;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
-
|
|
104
|
+
protected postMessage(editorId: string, rendererId: string, message: unknown): void {
|
|
105
105
|
if (!this.activations.has(rendererId)) {
|
|
106
106
|
this.prepare(rendererId);
|
|
107
107
|
}
|
|
@@ -187,6 +187,14 @@
|
|
|
187
187
|
overflow: hidden;
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
+
.theia-notebook-main-container .theia-notebook-main-loading-indicator {
|
|
191
|
+
/* `progress-animation` is defined in `packages/core/src/browser/style/progress-bar.css` */
|
|
192
|
+
animation: progress-animation 1.8s 0s infinite
|
|
193
|
+
cubic-bezier(0.645, 0.045, 0.355, 1);
|
|
194
|
+
background-color: var(--theia-progressBar-background);
|
|
195
|
+
height: 2px;
|
|
196
|
+
}
|
|
197
|
+
|
|
190
198
|
.theia-notebook-viewport {
|
|
191
199
|
display: flex;
|
|
192
200
|
overflow: hidden;
|
|
@@ -286,6 +294,7 @@
|
|
|
286
294
|
position: absolute;
|
|
287
295
|
top: -99999px;
|
|
288
296
|
left: -99999px;
|
|
289
|
-
height: 500px;
|
|
290
|
-
|
|
297
|
+
max-height: 500px;
|
|
298
|
+
min-height: 100px;
|
|
299
|
+
background-color: var(--theia-editor-background);
|
|
291
300
|
}
|
|
@@ -26,6 +26,7 @@ import { DisposableCollection, OS } from '@theia/core';
|
|
|
26
26
|
import { NotebookViewportService } from './notebook-viewport-service';
|
|
27
27
|
import { BareFontInfo } from '@theia/monaco-editor-core/esm/vs/editor/common/config/fontInfo';
|
|
28
28
|
import { NOTEBOOK_CELL_CURSOR_FIRST_LINE, NOTEBOOK_CELL_CURSOR_LAST_LINE } from '../contributions/notebook-context-keys';
|
|
29
|
+
import { EditorExtensionsRegistry } from '@theia/monaco-editor-core/esm/vs/editor/browser/editorExtensions';
|
|
29
30
|
|
|
30
31
|
interface CellEditorProps {
|
|
31
32
|
notebookModel: NotebookModel,
|
|
@@ -117,7 +118,8 @@ export class CellEditor extends React.Component<CellEditorProps, {}> {
|
|
|
117
118
|
editorNode,
|
|
118
119
|
monacoServices,
|
|
119
120
|
{ ...DEFAULT_EDITOR_OPTIONS, ...cell.editorOptions },
|
|
120
|
-
[[IContextKeyService, this.props.notebookContextManager.scopedStore]]
|
|
121
|
+
[[IContextKeyService, this.props.notebookContextManager.scopedStore]],
|
|
122
|
+
{ contributions: EditorExtensionsRegistry.getEditorContributions().filter(c => c.id !== 'editor.contrib.findController') });
|
|
121
123
|
this.toDispose.push(this.editor);
|
|
122
124
|
this.editor.setLanguage(cell.language);
|
|
123
125
|
this.toDispose.push(this.editor.getControl().onDidContentSizeChange(() => {
|
|
@@ -45,7 +45,7 @@ export class NotebookCellListView extends React.Component<CellListProps, Noteboo
|
|
|
45
45
|
|
|
46
46
|
protected toDispose = new DisposableCollection();
|
|
47
47
|
|
|
48
|
-
protected dragGhost: HTMLElement | undefined;
|
|
48
|
+
protected static dragGhost: HTMLElement | undefined;
|
|
49
49
|
|
|
50
50
|
constructor(props: CellListProps) {
|
|
51
51
|
super(props);
|
|
@@ -96,6 +96,10 @@ export class NotebookCellListView extends React.Component<CellListProps, Noteboo
|
|
|
96
96
|
this.props.notebookModel.setSelectedCell(cell, false);
|
|
97
97
|
}}
|
|
98
98
|
onDragStart={e => this.onDragStart(e, index, cell)}
|
|
99
|
+
onDragEnd={e => {
|
|
100
|
+
NotebookCellListView.dragGhost?.remove();
|
|
101
|
+
this.setState({ ...this.state, dragOverIndicator: undefined });
|
|
102
|
+
}}
|
|
99
103
|
onDragOver={e => this.onDragOver(e, cell)}
|
|
100
104
|
onDrop={e => this.onDrop(e, index)}
|
|
101
105
|
draggable={true}
|
|
@@ -137,14 +141,11 @@ export class NotebookCellListView extends React.Component<CellListProps, Noteboo
|
|
|
137
141
|
return;
|
|
138
142
|
}
|
|
139
143
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
this.dragGhost.appendChild(this.props.renderers.get(cell.cellKind)?.renderDragImage(cell) ?? document.createElement('div'));
|
|
146
|
-
document.body.appendChild(this.dragGhost);
|
|
147
|
-
event.dataTransfer.setDragImage(this.dragGhost, -10, 0);
|
|
144
|
+
NotebookCellListView.dragGhost = document.createElement('div');
|
|
145
|
+
NotebookCellListView.dragGhost.classList.add('theia-notebook-drag-ghost-image');
|
|
146
|
+
NotebookCellListView.dragGhost.appendChild(this.props.renderers.get(cell.cellKind)?.renderDragImage(cell) ?? document.createElement('div'));
|
|
147
|
+
document.body.appendChild(NotebookCellListView.dragGhost);
|
|
148
|
+
event.dataTransfer.setDragImage(NotebookCellListView.dragGhost, -10, 0);
|
|
148
149
|
|
|
149
150
|
event.dataTransfer.setData('text/theia-notebook-cell-index', index.toString());
|
|
150
151
|
event.dataTransfer.setData('text/plain', this.props.notebookModel.cells[index].source);
|
|
@@ -32,8 +32,9 @@ import { CommandRegistry, DisposableCollection, nls } from '@theia/core';
|
|
|
32
32
|
import { NotebookContextManager } from '../service/notebook-context-manager';
|
|
33
33
|
import { NotebookViewportService } from './notebook-viewport-service';
|
|
34
34
|
import { EditorPreferences } from '@theia/editor/lib/browser';
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
35
|
+
import { NotebookOptionsService } from '../service/notebook-options';
|
|
36
|
+
import { MarkdownRenderer } from '@theia/core/lib/browser/markdown-rendering/markdown-renderer';
|
|
37
|
+
import { MarkdownString } from '@theia/monaco-editor-core/esm/vs/base/common/htmlContent';
|
|
37
38
|
|
|
38
39
|
@injectable()
|
|
39
40
|
export class NotebookCodeCellRenderer implements CellRenderer {
|
|
@@ -64,7 +65,11 @@ export class NotebookCodeCellRenderer implements CellRenderer {
|
|
|
64
65
|
@inject(CommandRegistry)
|
|
65
66
|
protected readonly commandRegistry: CommandRegistry;
|
|
66
67
|
|
|
67
|
-
|
|
68
|
+
@inject(NotebookOptionsService)
|
|
69
|
+
protected readonly notebookOptionsService: NotebookOptionsService;
|
|
70
|
+
|
|
71
|
+
@inject(MarkdownRenderer)
|
|
72
|
+
protected readonly markdownRenderer: MarkdownRenderer;
|
|
68
73
|
|
|
69
74
|
render(notebookModel: NotebookModel, cell: NotebookCellModel, handle: number): React.ReactNode {
|
|
70
75
|
return <div>
|
|
@@ -81,7 +86,7 @@ export class NotebookCodeCellRenderer implements CellRenderer {
|
|
|
81
86
|
monacoServices={this.monacoServices}
|
|
82
87
|
notebookContextManager={this.notebookContextManager}
|
|
83
88
|
notebookViewportService={this.notebookViewportService}
|
|
84
|
-
fontInfo={this.
|
|
89
|
+
fontInfo={this.notebookOptionsService.editorFontInfo} />
|
|
85
90
|
<NotebookCodeCellStatus cell={cell} notebook={notebookModel}
|
|
86
91
|
commandRegistry={this.commandRegistry}
|
|
87
92
|
executionStateService={this.executionStateService}
|
|
@@ -102,28 +107,43 @@ export class NotebookCodeCellRenderer implements CellRenderer {
|
|
|
102
107
|
renderDragImage(cell: NotebookCellModel): HTMLElement {
|
|
103
108
|
const dragImage = document.createElement('div');
|
|
104
109
|
dragImage.className = 'theia-notebook-drag-image';
|
|
105
|
-
dragImage.
|
|
110
|
+
dragImage.style.width = this.notebookContextManager.context?.clientWidth + 'px';
|
|
111
|
+
dragImage.style.height = '100px';
|
|
112
|
+
dragImage.style.display = 'flex';
|
|
113
|
+
|
|
114
|
+
const fakeRunButton = document.createElement('span');
|
|
115
|
+
fakeRunButton.className = `${codicon('play')} theia-notebook-cell-status-item`;
|
|
116
|
+
dragImage.appendChild(fakeRunButton);
|
|
117
|
+
|
|
118
|
+
const fakeEditor = document.createElement('div');
|
|
119
|
+
dragImage.appendChild(fakeEditor);
|
|
120
|
+
const lines = cell.source.split('\n').slice(0, 5).join('\n');
|
|
121
|
+
const codeSequence = this.getMarkdownCodeSequence(lines);
|
|
122
|
+
const firstLine = new MarkdownString(`${codeSequence}${cell.language}\n${lines}\n${codeSequence}`, { supportHtml: true, isTrusted: false });
|
|
123
|
+
fakeEditor.appendChild(this.markdownRenderer.render(firstLine).element);
|
|
124
|
+
fakeEditor.classList.add('theia-notebook-cell-editor-container');
|
|
125
|
+
fakeEditor.style.padding = '10px';
|
|
106
126
|
return dragImage;
|
|
107
127
|
}
|
|
108
128
|
|
|
109
|
-
protected
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
129
|
+
protected getMarkdownCodeSequence(input: string): string {
|
|
130
|
+
// We need a minimum of 3 backticks to start a code block.
|
|
131
|
+
let longest = 2;
|
|
132
|
+
let current = 0;
|
|
133
|
+
for (let i = 0; i < input.length; i++) {
|
|
134
|
+
const char = input.charAt(i);
|
|
135
|
+
if (char === '`') {
|
|
136
|
+
current++;
|
|
137
|
+
if (current > longest) {
|
|
138
|
+
longest = current;
|
|
139
|
+
}
|
|
140
|
+
} else {
|
|
141
|
+
current = 0;
|
|
142
|
+
}
|
|
113
143
|
}
|
|
114
|
-
return
|
|
144
|
+
return Array(longest + 1).fill('`').join('');
|
|
115
145
|
}
|
|
116
146
|
|
|
117
|
-
protected createFontInfo(): BareFontInfo {
|
|
118
|
-
return BareFontInfo.createFromRawSettings({
|
|
119
|
-
fontFamily: this.editorPreferences['editor.fontFamily'],
|
|
120
|
-
fontWeight: String(this.editorPreferences['editor.fontWeight']),
|
|
121
|
-
fontSize: this.editorPreferences['editor.fontSize'],
|
|
122
|
-
fontLigatures: this.editorPreferences['editor.fontLigatures'],
|
|
123
|
-
lineHeight: this.editorPreferences['editor.lineHeight'],
|
|
124
|
-
letterSpacing: this.editorPreferences['editor.letterSpacing'],
|
|
125
|
-
}, PixelRatio.value);
|
|
126
|
-
}
|
|
127
147
|
}
|
|
128
148
|
|
|
129
149
|
export interface NotebookCodeCellStatusProps {
|
|
@@ -44,8 +44,10 @@ export class NotebookMarkdownCellRenderer implements CellRenderer {
|
|
|
44
44
|
|
|
45
45
|
renderDragImage(cell: NotebookCellModel): HTMLElement {
|
|
46
46
|
const dragImage = document.createElement('div');
|
|
47
|
-
dragImage.
|
|
48
|
-
|
|
47
|
+
dragImage.style.width = this.notebookContextManager.context?.clientWidth + 'px';
|
|
48
|
+
const markdownString = new MarkdownStringImpl(cell.source, { supportHtml: true, isTrusted: true });
|
|
49
|
+
const markdownElement = this.markdownRenderer.render(markdownString).element;
|
|
50
|
+
dragImage.appendChild(markdownElement);
|
|
49
51
|
return dragImage;
|
|
50
52
|
}
|
|
51
53
|
}
|
|
@@ -30,7 +30,7 @@ import { NotebookCellOutputsSplice } from '../notebook-types';
|
|
|
30
30
|
import { NotebookMonacoTextModelService } from '../service/notebook-monaco-text-model-service';
|
|
31
31
|
import { NotebookCellOutputModel } from './notebook-cell-output-model';
|
|
32
32
|
import { PreferenceService } from '@theia/core/lib/browser';
|
|
33
|
-
import {
|
|
33
|
+
import { NotebookPreferences } from '../contributions/notebook-preferences';
|
|
34
34
|
import { LanguageService } from '@theia/core/lib/browser/language-service';
|
|
35
35
|
|
|
36
36
|
export const NotebookCellModelFactory = Symbol('NotebookModelFactory');
|
|
@@ -245,13 +245,13 @@ export class NotebookCellModel implements NotebookCell, Disposable {
|
|
|
245
245
|
this._internalMetadata = this.props.internalMetadata ?? {};
|
|
246
246
|
|
|
247
247
|
this.editorOptions = {
|
|
248
|
-
lineNumbers: this.preferenceService.get(NOTEBOOK_LINE_NUMBERS)
|
|
248
|
+
lineNumbers: this.preferenceService.get(NotebookPreferences.NOTEBOOK_LINE_NUMBERS)
|
|
249
249
|
};
|
|
250
250
|
this.toDispose.push(this.preferenceService.onPreferenceChanged(e => {
|
|
251
|
-
if (e.preferenceName === NOTEBOOK_LINE_NUMBERS) {
|
|
251
|
+
if (e.preferenceName === NotebookPreferences.NOTEBOOK_LINE_NUMBERS) {
|
|
252
252
|
this.editorOptions = {
|
|
253
253
|
...this.editorOptions,
|
|
254
|
-
lineNumbers: this.preferenceService.get(NOTEBOOK_LINE_NUMBERS)
|
|
254
|
+
lineNumbers: this.preferenceService.get(NotebookPreferences.NOTEBOOK_LINE_NUMBERS)
|
|
255
255
|
};
|
|
256
256
|
}
|
|
257
257
|
}));
|
|
@@ -38,7 +38,7 @@ export class NotebookCellOutputModel implements Disposable {
|
|
|
38
38
|
return this.rawOutput.metadata;
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
constructor(
|
|
41
|
+
constructor(protected rawOutput: CellOutput) { }
|
|
42
42
|
|
|
43
43
|
replaceData(rawData: CellOutput): void {
|
|
44
44
|
this.rawOutput = rawData;
|