@theia/notebook 1.41.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/README.md +30 -0
- package/lib/browser/contributions/notebook-actions-contribution.d.ts +27 -0
- package/lib/browser/contributions/notebook-actions-contribution.d.ts.map +1 -0
- package/lib/browser/contributions/notebook-actions-contribution.js +172 -0
- package/lib/browser/contributions/notebook-actions-contribution.js.map +1 -0
- package/lib/browser/contributions/notebook-cell-actions-contribution.d.ts +30 -0
- package/lib/browser/contributions/notebook-cell-actions-contribution.d.ts.map +1 -0
- package/lib/browser/contributions/notebook-cell-actions-contribution.js +200 -0
- package/lib/browser/contributions/notebook-cell-actions-contribution.js.map +1 -0
- package/lib/browser/contributions/notebook-color-contribution.d.ts +6 -0
- package/lib/browser/contributions/notebook-color-contribution.d.ts.map +1 -0
- package/lib/browser/contributions/notebook-color-contribution.js +252 -0
- package/lib/browser/contributions/notebook-color-contribution.js.map +1 -0
- package/lib/browser/contributions/notebook-context-keys.d.ts +38 -0
- package/lib/browser/contributions/notebook-context-keys.d.ts.map +1 -0
- package/lib/browser/contributions/notebook-context-keys.js +95 -0
- package/lib/browser/contributions/notebook-context-keys.js.map +1 -0
- package/lib/browser/index.d.ts +11 -0
- package/lib/browser/index.d.ts.map +1 -0
- package/lib/browser/index.js +38 -0
- package/lib/browser/index.js.map +1 -0
- package/lib/browser/notebook-cell-resource-resolver.d.ts +20 -0
- package/lib/browser/notebook-cell-resource-resolver.d.ts.map +1 -0
- package/lib/browser/notebook-cell-resource-resolver.js +75 -0
- package/lib/browser/notebook-cell-resource-resolver.js.map +1 -0
- package/lib/browser/notebook-editor-widget-factory.d.ts +17 -0
- package/lib/browser/notebook-editor-widget-factory.d.ts.map +1 -0
- package/lib/browser/notebook-editor-widget-factory.js +78 -0
- package/lib/browser/notebook-editor-widget-factory.js.map +1 -0
- package/lib/browser/notebook-editor-widget.d.ts +49 -0
- package/lib/browser/notebook-editor-widget.d.ts.map +1 -0
- package/lib/browser/notebook-editor-widget.js +150 -0
- package/lib/browser/notebook-editor-widget.js.map +1 -0
- package/lib/browser/notebook-frontend-module.d.ts +5 -0
- package/lib/browser/notebook-frontend-module.d.ts.map +1 -0
- package/lib/browser/notebook-frontend-module.js +81 -0
- package/lib/browser/notebook-frontend-module.js.map +1 -0
- package/lib/browser/notebook-open-handler.d.ts +18 -0
- package/lib/browser/notebook-open-handler.d.ts.map +1 -0
- package/lib/browser/notebook-open-handler.js +94 -0
- package/lib/browser/notebook-open-handler.js.map +1 -0
- package/lib/browser/notebook-renderer-registry.d.ts +17 -0
- package/lib/browser/notebook-renderer-registry.d.ts.map +1 -0
- package/lib/browser/notebook-renderer-registry.js +63 -0
- package/lib/browser/notebook-renderer-registry.js.map +1 -0
- package/lib/browser/notebook-type-registry.d.ts +7 -0
- package/lib/browser/notebook-type-registry.d.ts.map +1 -0
- package/lib/browser/notebook-type-registry.js +42 -0
- package/lib/browser/notebook-type-registry.js.map +1 -0
- package/lib/browser/renderers/cell-output-webview.d.ts +12 -0
- package/lib/browser/renderers/cell-output-webview.d.ts.map +1 -0
- package/lib/browser/renderers/cell-output-webview.js +20 -0
- package/lib/browser/renderers/cell-output-webview.js.map +1 -0
- package/lib/browser/service/notebook-cell-context-manager.d.ts +16 -0
- package/lib/browser/service/notebook-cell-context-manager.d.ts.map +1 -0
- package/lib/browser/service/notebook-cell-context-manager.js +83 -0
- package/lib/browser/service/notebook-cell-context-manager.js.map +1 -0
- package/lib/browser/service/notebook-editor-service.d.ts +22 -0
- package/lib/browser/service/notebook-editor-service.d.ts.map +1 -0
- package/lib/browser/service/notebook-editor-service.js +95 -0
- package/lib/browser/service/notebook-editor-service.js.map +1 -0
- package/lib/browser/service/notebook-execution-service.d.ts +25 -0
- package/lib/browser/service/notebook-execution-service.d.ts.map +1 -0
- package/lib/browser/service/notebook-execution-service.js +140 -0
- package/lib/browser/service/notebook-execution-service.js.map +1 -0
- package/lib/browser/service/notebook-execution-state-service.d.ts +94 -0
- package/lib/browser/service/notebook-execution-state-service.d.ts.map +1 -0
- package/lib/browser/service/notebook-execution-state-service.js +250 -0
- package/lib/browser/service/notebook-execution-state-service.js.map +1 -0
- package/lib/browser/service/notebook-kernel-history-service.d.ts +23 -0
- package/lib/browser/service/notebook-kernel-history-service.d.ts.map +1 -0
- package/lib/browser/service/notebook-kernel-history-service.js +109 -0
- package/lib/browser/service/notebook-kernel-history-service.js.map +1 -0
- package/lib/browser/service/notebook-kernel-quick-pick-service.d.ts +65 -0
- package/lib/browser/service/notebook-kernel-quick-pick-service.d.ts.map +1 -0
- package/lib/browser/service/notebook-kernel-quick-pick-service.js +430 -0
- package/lib/browser/service/notebook-kernel-quick-pick-service.js.map +1 -0
- package/lib/browser/service/notebook-kernel-service.d.ts +112 -0
- package/lib/browser/service/notebook-kernel-service.d.ts.map +1 -0
- package/lib/browser/service/notebook-kernel-service.js +274 -0
- package/lib/browser/service/notebook-kernel-service.js.map +1 -0
- package/lib/browser/service/notebook-model-resolver-service.d.ts +26 -0
- package/lib/browser/service/notebook-model-resolver-service.d.ts.map +1 -0
- package/lib/browser/service/notebook-model-resolver-service.js +139 -0
- package/lib/browser/service/notebook-model-resolver-service.js.map +1 -0
- package/lib/browser/service/notebook-renderer-messaging-service.d.ts +30 -0
- package/lib/browser/service/notebook-renderer-messaging-service.d.ts.map +1 -0
- package/lib/browser/service/notebook-renderer-messaging-service.js +94 -0
- package/lib/browser/service/notebook-renderer-messaging-service.js.map +1 -0
- package/lib/browser/service/notebook-service.d.ts +64 -0
- package/lib/browser/service/notebook-service.d.ts.map +1 -0
- package/lib/browser/service/notebook-service.js +162 -0
- package/lib/browser/service/notebook-service.js.map +1 -0
- package/lib/browser/view/notebook-cell-editor.d.ts +26 -0
- package/lib/browser/view/notebook-cell-editor.d.ts.map +1 -0
- package/lib/browser/view/notebook-cell-editor.js +79 -0
- package/lib/browser/view/notebook-cell-editor.js.map +1 -0
- package/lib/browser/view/notebook-cell-list-view.d.ts +43 -0
- package/lib/browser/view/notebook-cell-list-view.d.ts.map +1 -0
- package/lib/browser/view/notebook-cell-list-view.js +111 -0
- package/lib/browser/view/notebook-cell-list-view.js.map +1 -0
- package/lib/browser/view/notebook-cell-toolbar-factory.d.ts +25 -0
- package/lib/browser/view/notebook-cell-toolbar-factory.d.ts.map +1 -0
- package/lib/browser/view/notebook-cell-toolbar-factory.js +93 -0
- package/lib/browser/view/notebook-cell-toolbar-factory.js.map +1 -0
- package/lib/browser/view/notebook-cell-toolbar.d.ts +25 -0
- package/lib/browser/view/notebook-cell-toolbar.d.ts.map +1 -0
- package/lib/browser/view/notebook-cell-toolbar.js +50 -0
- package/lib/browser/view/notebook-cell-toolbar.js.map +1 -0
- package/lib/browser/view/notebook-code-cell-view.d.ts +47 -0
- package/lib/browser/view/notebook-code-cell-view.d.ts.map +1 -0
- package/lib/browser/view/notebook-code-cell-view.js +166 -0
- package/lib/browser/view/notebook-code-cell-view.js.map +1 -0
- package/lib/browser/view/notebook-main-toolbar.d.ts +31 -0
- package/lib/browser/view/notebook-main-toolbar.d.ts.map +1 -0
- package/lib/browser/view/notebook-main-toolbar.js +118 -0
- package/lib/browser/view/notebook-main-toolbar.js.map +1 -0
- package/lib/browser/view/notebook-markdown-cell-view.d.ts +12 -0
- package/lib/browser/view/notebook-markdown-cell-view.d.ts.map +1 -0
- package/lib/browser/view/notebook-markdown-cell-view.js +70 -0
- package/lib/browser/view/notebook-markdown-cell-view.js.map +1 -0
- package/lib/browser/view-model/notebook-cell-model.d.ts +74 -0
- package/lib/browser/view-model/notebook-cell-model.d.ts.map +1 -0
- package/lib/browser/view-model/notebook-cell-model.js +226 -0
- package/lib/browser/view-model/notebook-cell-model.js.map +1 -0
- package/lib/browser/view-model/notebook-cell-output-model.d.ts +19 -0
- package/lib/browser/view-model/notebook-cell-output-model.d.ts.map +1 -0
- package/lib/browser/view-model/notebook-cell-output-model.js +61 -0
- package/lib/browser/view-model/notebook-cell-output-model.js.map +1 -0
- package/lib/browser/view-model/notebook-model.d.ts +59 -0
- package/lib/browser/view-model/notebook-model.d.ts.map +1 -0
- package/lib/browser/view-model/notebook-model.js +315 -0
- package/lib/browser/view-model/notebook-model.js.map +1 -0
- package/lib/common/index.d.ts +3 -0
- package/lib/common/index.d.ts.map +1 -0
- package/lib/common/index.js +30 -0
- package/lib/common/index.js.map +1 -0
- package/lib/common/notebook-common.d.ts +344 -0
- package/lib/common/notebook-common.d.ts.map +1 -0
- package/lib/common/notebook-common.js +112 -0
- package/lib/common/notebook-common.js.map +1 -0
- package/lib/common/notebook-protocol.d.ts +21 -0
- package/lib/common/notebook-protocol.d.ts.map +1 -0
- package/lib/common/notebook-protocol.js +18 -0
- package/lib/common/notebook-protocol.js.map +1 -0
- package/lib/common/notebook-range.d.ts +14 -0
- package/lib/common/notebook-range.d.ts.map +1 -0
- package/lib/common/notebook-range.js +18 -0
- package/lib/common/notebook-range.js.map +1 -0
- package/package.json +52 -0
- package/src/browser/contributions/notebook-actions-contribution.ts +171 -0
- package/src/browser/contributions/notebook-cell-actions-contribution.ts +204 -0
- package/src/browser/contributions/notebook-color-contribution.ts +268 -0
- package/src/browser/contributions/notebook-context-keys.ts +99 -0
- package/src/browser/index.ts +26 -0
- package/src/browser/notebook-cell-resource-resolver.ts +79 -0
- package/src/browser/notebook-editor-widget-factory.ts +70 -0
- package/src/browser/notebook-editor-widget.tsx +157 -0
- package/src/browser/notebook-frontend-module.ts +95 -0
- package/src/browser/notebook-open-handler.ts +87 -0
- package/src/browser/notebook-renderer-registry.ts +62 -0
- package/src/browser/notebook-type-registry.ts +30 -0
- package/src/browser/renderers/cell-output-webview.ts +32 -0
- package/src/browser/service/notebook-cell-context-manager.ts +70 -0
- package/src/browser/service/notebook-editor-service.ts +86 -0
- package/src/browser/service/notebook-execution-service.ts +139 -0
- package/src/browser/service/notebook-execution-state-service.ts +322 -0
- package/src/browser/service/notebook-kernel-history-service.ts +109 -0
- package/src/browser/service/notebook-kernel-quick-pick-service.ts +494 -0
- package/src/browser/service/notebook-kernel-service.ts +357 -0
- package/src/browser/service/notebook-model-resolver-service.ts +141 -0
- package/src/browser/service/notebook-renderer-messaging-service.ts +111 -0
- package/src/browser/service/notebook-service.ts +178 -0
- package/src/browser/style/index.css +236 -0
- package/src/browser/view/notebook-cell-editor.tsx +97 -0
- package/src/browser/view/notebook-cell-list-view.tsx +171 -0
- package/src/browser/view/notebook-cell-toolbar-factory.tsx +91 -0
- package/src/browser/view/notebook-cell-toolbar.tsx +70 -0
- package/src/browser/view/notebook-code-cell-view.tsx +190 -0
- package/src/browser/view/notebook-main-toolbar.tsx +115 -0
- package/src/browser/view/notebook-markdown-cell-view.tsx +73 -0
- package/src/browser/view-model/notebook-cell-model.ts +271 -0
- package/src/browser/view-model/notebook-cell-output-model.ts +69 -0
- package/src/browser/view-model/notebook-model.ts +372 -0
- package/src/common/index.ts +18 -0
- package/src/common/notebook-common.ts +462 -0
- package/src/common/notebook-protocol.ts +35 -0
- package/src/common/notebook-range.ts +30 -0
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2023 TypeFox and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
/*---------------------------------------------------------------------------------------------
|
|
17
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
18
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
19
|
+
*--------------------------------------------------------------------------------------------*/
|
|
20
|
+
|
|
21
|
+
import { Command, CommandRegistry, Disposable, Emitter, Event, URI } from '@theia/core';
|
|
22
|
+
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
|
|
23
|
+
import { StorageService } from '@theia/core/lib/browser';
|
|
24
|
+
import { NotebookKernelSourceAction } from '../../common';
|
|
25
|
+
import { NotebookModel } from '../view-model/notebook-model';
|
|
26
|
+
import { NotebookService } from './notebook-service';
|
|
27
|
+
|
|
28
|
+
export interface SelectedNotebookKernelChangeEvent {
|
|
29
|
+
notebook: URI;
|
|
30
|
+
oldKernel: string | undefined;
|
|
31
|
+
newKernel: string | undefined;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface NotebookKernelMatchResult {
|
|
35
|
+
readonly selected: NotebookKernel | undefined;
|
|
36
|
+
readonly suggestions: NotebookKernel[];
|
|
37
|
+
readonly all: NotebookKernel[];
|
|
38
|
+
readonly hidden: NotebookKernel[];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface NotebookKernelChangeEvent {
|
|
42
|
+
label?: true;
|
|
43
|
+
description?: true;
|
|
44
|
+
detail?: true;
|
|
45
|
+
supportedLanguages?: true;
|
|
46
|
+
hasExecutionOrder?: true;
|
|
47
|
+
hasInterruptHandler?: true;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface NotebookKernel {
|
|
51
|
+
readonly id: string;
|
|
52
|
+
readonly viewType: string;
|
|
53
|
+
readonly onDidChange: Event<Readonly<NotebookKernelChangeEvent>>;
|
|
54
|
+
readonly extension: string;
|
|
55
|
+
|
|
56
|
+
readonly localResourceRoot: URI;
|
|
57
|
+
readonly preloadUris: URI[];
|
|
58
|
+
readonly preloadProvides: string[];
|
|
59
|
+
|
|
60
|
+
label: string;
|
|
61
|
+
description?: string;
|
|
62
|
+
detail?: string;
|
|
63
|
+
supportedLanguages: string[];
|
|
64
|
+
implementsInterrupt?: boolean;
|
|
65
|
+
implementsExecutionOrder?: boolean;
|
|
66
|
+
|
|
67
|
+
executeNotebookCellsRequest(uri: URI, cellHandles: number[]): Promise<void>;
|
|
68
|
+
cancelNotebookCellExecution(uri: URI, cellHandles: number[]): Promise<void>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const enum ProxyKernelState {
|
|
72
|
+
Disconnected = 1,
|
|
73
|
+
Connected = 2,
|
|
74
|
+
Initializing = 3
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface INotebookProxyKernelChangeEvent extends NotebookKernelChangeEvent {
|
|
78
|
+
connectionState?: true;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface NotebookKernelDetectionTask {
|
|
82
|
+
readonly notebookType: string;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export interface NotebookTextModelLike { uri: URI; viewType: string }
|
|
86
|
+
|
|
87
|
+
class KernelInfo {
|
|
88
|
+
|
|
89
|
+
private static logicClock = 0;
|
|
90
|
+
|
|
91
|
+
readonly kernel: NotebookKernel;
|
|
92
|
+
public score: number;
|
|
93
|
+
readonly time: number;
|
|
94
|
+
|
|
95
|
+
constructor(kernel: NotebookKernel) {
|
|
96
|
+
this.kernel = kernel;
|
|
97
|
+
this.score = -1;
|
|
98
|
+
this.time = KernelInfo.logicClock++;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface NotebookSourceActionChangeEvent {
|
|
103
|
+
notebook?: URI;
|
|
104
|
+
viewType: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface KernelSourceActionProvider {
|
|
108
|
+
readonly viewType: string;
|
|
109
|
+
onDidChangeSourceActions?: Event<void>;
|
|
110
|
+
provideKernelSourceActions(): Promise<NotebookKernelSourceAction[]>;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export class SourceCommand implements Disposable {
|
|
114
|
+
execution: Promise<void> | undefined;
|
|
115
|
+
protected readonly onDidChangeStateEmitter = new Emitter<void>();
|
|
116
|
+
readonly onDidChangeState = this.onDidChangeStateEmitter.event;
|
|
117
|
+
|
|
118
|
+
constructor(
|
|
119
|
+
readonly commandRegistry: CommandRegistry,
|
|
120
|
+
readonly command: Command,
|
|
121
|
+
readonly model: NotebookTextModelLike,
|
|
122
|
+
readonly isPrimary: boolean
|
|
123
|
+
) { }
|
|
124
|
+
|
|
125
|
+
async run(): Promise<void> {
|
|
126
|
+
if (this.execution) {
|
|
127
|
+
return this.execution;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
this.execution = this.runCommand();
|
|
131
|
+
this.onDidChangeStateEmitter.fire();
|
|
132
|
+
await this.execution;
|
|
133
|
+
this.execution = undefined;
|
|
134
|
+
this.onDidChangeStateEmitter.fire();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
private async runCommand(): Promise<void> {
|
|
138
|
+
try {
|
|
139
|
+
await this.commandRegistry.executeCommand(this.command.id, {
|
|
140
|
+
uri: this.model.uri,
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
} catch (error) {
|
|
144
|
+
console.warn(`Kernel source command failed: ${error}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
dispose(): void {
|
|
149
|
+
this.onDidChangeStateEmitter.dispose();
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
const NOTEBOOK_KERNEL_BINDING_STORAGE_KEY = 'notebook.kernel.bindings';
|
|
155
|
+
@injectable()
|
|
156
|
+
export class NotebookKernelService implements Disposable {
|
|
157
|
+
|
|
158
|
+
@inject(NotebookService)
|
|
159
|
+
protected notebookService: NotebookService;
|
|
160
|
+
|
|
161
|
+
@inject(StorageService)
|
|
162
|
+
protected storageService: StorageService;
|
|
163
|
+
|
|
164
|
+
private readonly kernels = new Map<string, KernelInfo>();
|
|
165
|
+
|
|
166
|
+
private notebookBindings: { [key: string]: string } = {};
|
|
167
|
+
|
|
168
|
+
private readonly kernelDetectionTasks = new Map<string, NotebookKernelDetectionTask[]>();
|
|
169
|
+
private readonly onDidChangeKernelDetectionTasksEmitter = new Emitter<string>();
|
|
170
|
+
readonly onDidChangeKernelDetectionTasks = this.onDidChangeKernelDetectionTasksEmitter.event;
|
|
171
|
+
|
|
172
|
+
private readonly onDidChangeSourceActionsEmitter = new Emitter<NotebookSourceActionChangeEvent>();
|
|
173
|
+
private readonly kernelSourceActionProviders = new Map<string, KernelSourceActionProvider[]>();
|
|
174
|
+
readonly onDidChangeSourceActions: Event<NotebookSourceActionChangeEvent> = this.onDidChangeSourceActionsEmitter.event;
|
|
175
|
+
|
|
176
|
+
private readonly onDidAddKernelEmitter = new Emitter<NotebookKernel>();
|
|
177
|
+
readonly onDidAddKernel: Event<NotebookKernel> = this.onDidAddKernelEmitter.event;
|
|
178
|
+
|
|
179
|
+
private readonly onDidRemoveKernelEmitter = new Emitter<NotebookKernel>();
|
|
180
|
+
readonly onDidRemoveKernel: Event<NotebookKernel> = this.onDidRemoveKernelEmitter.event;
|
|
181
|
+
|
|
182
|
+
private readonly onDidChangeSelectedNotebookKernelBindingEmitter = new Emitter<SelectedNotebookKernelChangeEvent>();
|
|
183
|
+
readonly onDidChangeSelectedKernel: Event<SelectedNotebookKernelChangeEvent> = this.onDidChangeSelectedNotebookKernelBindingEmitter.event;
|
|
184
|
+
|
|
185
|
+
private readonly onDidChangeNotebookAffinityEmitter = new Emitter<void>();
|
|
186
|
+
readonly onDidChangeNotebookAffinity: Event<void> = this.onDidChangeNotebookAffinityEmitter.event;
|
|
187
|
+
|
|
188
|
+
@postConstruct()
|
|
189
|
+
init(): void {
|
|
190
|
+
this.storageService.getData(NOTEBOOK_KERNEL_BINDING_STORAGE_KEY).then((value: { [key: string]: string } | undefined) => {
|
|
191
|
+
if (value) {
|
|
192
|
+
this.notebookBindings = value;
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
registerKernel(kernel: NotebookKernel): Disposable {
|
|
198
|
+
if (this.kernels.has(kernel.id)) {
|
|
199
|
+
throw new Error(`NOTEBOOK CONTROLLER with id '${kernel.id}' already exists`);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
this.kernels.set(kernel.id, new KernelInfo(kernel));
|
|
203
|
+
this.onDidAddKernelEmitter.fire(kernel);
|
|
204
|
+
|
|
205
|
+
// auto associate the new kernel to existing notebooks it was
|
|
206
|
+
// associated to in the past.
|
|
207
|
+
for (const notebook of this.notebookService.getNotebookModels()) {
|
|
208
|
+
this.tryAutoBindNotebook(notebook, kernel);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return Disposable.create(() => {
|
|
212
|
+
if (this.kernels.delete(kernel.id)) {
|
|
213
|
+
this.onDidRemoveKernelEmitter.fire(kernel);
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
getMatchingKernel(notebook: NotebookTextModelLike): NotebookKernelMatchResult {
|
|
219
|
+
const kernels: { kernel: NotebookKernel; instanceAffinity: number; score: number }[] = [];
|
|
220
|
+
for (const info of this.kernels.values()) {
|
|
221
|
+
const score = NotebookKernelService.score(info.kernel, notebook);
|
|
222
|
+
if (score) {
|
|
223
|
+
kernels.push({
|
|
224
|
+
score,
|
|
225
|
+
kernel: info.kernel,
|
|
226
|
+
instanceAffinity: 1 /* vscode.NotebookControllerPriority.Default */,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
kernels
|
|
232
|
+
.sort((a, b) => b.instanceAffinity - a.instanceAffinity || a.score - b.score || a.kernel.label.localeCompare(b.kernel.label));
|
|
233
|
+
const all = kernels.map(obj => obj.kernel);
|
|
234
|
+
|
|
235
|
+
// bound kernel
|
|
236
|
+
const selectedId = this.notebookBindings[`${notebook.viewType}/${notebook.uri}`];
|
|
237
|
+
const selected = selectedId ? this.kernels.get(selectedId)?.kernel : undefined;
|
|
238
|
+
const suggestions = kernels.filter(item => item.instanceAffinity > 1).map(item => item.kernel); // TODO implement notebookAffinity
|
|
239
|
+
const hidden = kernels.filter(item => item.instanceAffinity < 0).map(item => item.kernel);
|
|
240
|
+
return { all, selected, suggestions, hidden };
|
|
241
|
+
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
selectKernelForNotebook(kernel: NotebookKernel | undefined, notebook: NotebookTextModelLike): void {
|
|
245
|
+
const key = `${notebook.viewType}/${notebook.uri}`;
|
|
246
|
+
const oldKernel = this.notebookBindings[key];
|
|
247
|
+
if (oldKernel !== kernel?.id) {
|
|
248
|
+
if (kernel) {
|
|
249
|
+
this.notebookBindings[key] = kernel.id;
|
|
250
|
+
} else {
|
|
251
|
+
delete this.notebookBindings[key];
|
|
252
|
+
}
|
|
253
|
+
this.storageService.setData(NOTEBOOK_KERNEL_BINDING_STORAGE_KEY, this.notebookBindings);
|
|
254
|
+
this.onDidChangeSelectedNotebookKernelBindingEmitter.fire({ notebook: notebook.uri, oldKernel, newKernel: kernel?.id });
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
getSelectedOrSuggestedKernel(notebook: NotebookModel): NotebookKernel | undefined {
|
|
259
|
+
const info = this.getMatchingKernel(notebook);
|
|
260
|
+
if (info.selected) {
|
|
261
|
+
return info.selected;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return info.all.length === 1 ? info.all[0] : undefined;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
getKernel(id: string): NotebookKernel | undefined {
|
|
268
|
+
return this.kernels.get(id)?.kernel;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
private static score(kernel: NotebookKernel, notebook: NotebookTextModelLike): number {
|
|
272
|
+
if (kernel.viewType === '*') {
|
|
273
|
+
return 5;
|
|
274
|
+
} else if (kernel.viewType === notebook.viewType) {
|
|
275
|
+
return 10;
|
|
276
|
+
} else {
|
|
277
|
+
return 0;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
private tryAutoBindNotebook(notebook: NotebookModel, onlyThisKernel?: NotebookKernel): void {
|
|
282
|
+
|
|
283
|
+
const id = this.notebookBindings[`${notebook.viewType}/${notebook.uri}`];
|
|
284
|
+
if (!id) {
|
|
285
|
+
// no kernel associated
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
288
|
+
const existingKernel = this.kernels.get(id);
|
|
289
|
+
if (!existingKernel || !NotebookKernelService.score(existingKernel.kernel, notebook)) {
|
|
290
|
+
// associated kernel not known, not matching
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
if (!onlyThisKernel || existingKernel.kernel === onlyThisKernel) {
|
|
294
|
+
this.onDidChangeSelectedNotebookKernelBindingEmitter.fire({ notebook: notebook.uri, oldKernel: undefined, newKernel: existingKernel.kernel.id });
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
registerNotebookKernelDetectionTask(task: NotebookKernelDetectionTask): Disposable {
|
|
299
|
+
const notebookType = task.notebookType;
|
|
300
|
+
const all = this.kernelDetectionTasks.get(notebookType) ?? [];
|
|
301
|
+
all.push(task);
|
|
302
|
+
this.kernelDetectionTasks.set(notebookType, all);
|
|
303
|
+
this.onDidChangeKernelDetectionTasksEmitter.fire(notebookType);
|
|
304
|
+
return Disposable.create(() => {
|
|
305
|
+
const allTasks = this.kernelDetectionTasks.get(notebookType) ?? [];
|
|
306
|
+
const taskIndex = allTasks.indexOf(task);
|
|
307
|
+
if (taskIndex >= 0) {
|
|
308
|
+
allTasks.splice(taskIndex, 1);
|
|
309
|
+
this.kernelDetectionTasks.set(notebookType, allTasks);
|
|
310
|
+
this.onDidChangeKernelDetectionTasksEmitter.fire(notebookType);
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
getKernelDetectionTasks(notebook: NotebookTextModelLike): NotebookKernelDetectionTask[] {
|
|
316
|
+
return this.kernelDetectionTasks.get(notebook.viewType) ?? [];
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
registerKernelSourceActionProvider(viewType: string, provider: KernelSourceActionProvider): Disposable {
|
|
320
|
+
const providers = this.kernelSourceActionProviders.get(viewType) ?? [];
|
|
321
|
+
providers.push(provider);
|
|
322
|
+
this.kernelSourceActionProviders.set(viewType, providers);
|
|
323
|
+
this.onDidChangeSourceActionsEmitter.fire({ viewType: viewType });
|
|
324
|
+
|
|
325
|
+
const eventEmitterDisposable = provider.onDidChangeSourceActions?.(() => {
|
|
326
|
+
this.onDidChangeSourceActionsEmitter.fire({ viewType: viewType });
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
return Disposable.create(() => {
|
|
330
|
+
const sourceProviders = this.kernelSourceActionProviders.get(viewType) ?? [];
|
|
331
|
+
const providerIndex = sourceProviders.indexOf(provider);
|
|
332
|
+
if (providerIndex >= 0) {
|
|
333
|
+
sourceProviders.splice(providerIndex, 1);
|
|
334
|
+
this.kernelSourceActionProviders.set(viewType, sourceProviders);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
eventEmitterDisposable?.dispose();
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
async getKernelSourceActionsFromProviders(notebook: NotebookTextModelLike): Promise<NotebookKernelSourceAction[]> {
|
|
342
|
+
const viewType = notebook.viewType;
|
|
343
|
+
const providers = this.kernelSourceActionProviders.get(viewType) ?? [];
|
|
344
|
+
const promises = providers.map(provider => provider.provideKernelSourceActions());
|
|
345
|
+
const allActions = await Promise.all(promises);
|
|
346
|
+
return allActions.flat();
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
dispose(): void {
|
|
350
|
+
this.onDidChangeKernelDetectionTasksEmitter.dispose();
|
|
351
|
+
this.onDidChangeSourceActionsEmitter.dispose();
|
|
352
|
+
this.onDidAddKernelEmitter.dispose();
|
|
353
|
+
this.onDidRemoveKernelEmitter.dispose();
|
|
354
|
+
this.onDidChangeSelectedNotebookKernelBindingEmitter.dispose();
|
|
355
|
+
this.onDidChangeNotebookAffinityEmitter.dispose();
|
|
356
|
+
}
|
|
357
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2023 TypeFox and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { Emitter, URI } from '@theia/core';
|
|
18
|
+
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
19
|
+
import { UriComponents } from '@theia/core/lib/common/uri';
|
|
20
|
+
import { FileService } from '@theia/filesystem/lib/browser/file-service';
|
|
21
|
+
import { CellKind, NotebookData } from '../../common';
|
|
22
|
+
import { NotebookModel } from '../view-model/notebook-model';
|
|
23
|
+
import { NotebookService } from './notebook-service';
|
|
24
|
+
import { NotebookTypeRegistry } from '../notebook-type-registry';
|
|
25
|
+
import { NotebookFileSelector } from '../../common/notebook-protocol';
|
|
26
|
+
|
|
27
|
+
export interface UntitledResource {
|
|
28
|
+
untitledResource: URI | undefined
|
|
29
|
+
}
|
|
30
|
+
@injectable()
|
|
31
|
+
export class NotebookModelResolverService {
|
|
32
|
+
|
|
33
|
+
@inject(FileService)
|
|
34
|
+
protected fileService: FileService;
|
|
35
|
+
|
|
36
|
+
@inject(NotebookService)
|
|
37
|
+
protected notebookService: NotebookService;
|
|
38
|
+
|
|
39
|
+
@inject(NotebookTypeRegistry)
|
|
40
|
+
protected notebookTypeRegistry: NotebookTypeRegistry;
|
|
41
|
+
|
|
42
|
+
protected onDidChangeDirtyEmitter = new Emitter<NotebookModel>();
|
|
43
|
+
readonly onDidChangeDirty = this.onDidChangeDirtyEmitter.event;
|
|
44
|
+
protected onDidSaveNotebookEmitter = new Emitter<UriComponents>();
|
|
45
|
+
readonly onDidSaveNotebook = this.onDidSaveNotebookEmitter.event;
|
|
46
|
+
|
|
47
|
+
async resolve(resource: URI, viewType?: string): Promise<NotebookModel>;
|
|
48
|
+
async resolve(resource: UntitledResource, viewType: string): Promise<NotebookModel>;
|
|
49
|
+
async resolve(arg: URI | UntitledResource, viewType: string): Promise<NotebookModel> {
|
|
50
|
+
let resource: URI;
|
|
51
|
+
// let hasAssociatedFilePath = false;
|
|
52
|
+
if (arg instanceof URI) {
|
|
53
|
+
resource = arg;
|
|
54
|
+
} else {
|
|
55
|
+
arg = arg as UntitledResource;
|
|
56
|
+
if (!arg.untitledResource) {
|
|
57
|
+
const notebookTypeInfo = this.notebookTypeRegistry.notebookTypes.find(info => info.type === viewType);
|
|
58
|
+
if (!notebookTypeInfo) {
|
|
59
|
+
throw new Error('UNKNOWN view type: ' + viewType);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const suffix = this.getPossibleFileEndings(notebookTypeInfo.selector ?? []) ?? '';
|
|
63
|
+
for (let counter = 1; ; counter++) {
|
|
64
|
+
const candidate = new URI()
|
|
65
|
+
.withScheme('untitled')
|
|
66
|
+
.withPath(`Untitled-notebook-${counter}${suffix}`)
|
|
67
|
+
.withQuery(viewType);
|
|
68
|
+
if (!this.notebookService.getNotebookEditorModel(candidate)) {
|
|
69
|
+
resource = candidate;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
} else if (arg.untitledResource.scheme === 'untitled') {
|
|
74
|
+
resource = arg.untitledResource;
|
|
75
|
+
} else {
|
|
76
|
+
resource = arg.untitledResource.withScheme('untitled');
|
|
77
|
+
// hasAssociatedFilePath = true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const notebookData = await this.resolveExistingNotebookData(resource, viewType!);
|
|
82
|
+
|
|
83
|
+
const notebookModel = await this.notebookService.createNotebookModel(notebookData, viewType, resource);
|
|
84
|
+
|
|
85
|
+
notebookModel.onDirtyChanged(() => this.onDidChangeDirtyEmitter.fire(notebookModel));
|
|
86
|
+
notebookModel.onDidSaveNotebook(() => this.onDidSaveNotebookEmitter.fire(notebookModel.uri.toComponents()));
|
|
87
|
+
|
|
88
|
+
return notebookModel;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
protected async resolveExistingNotebookData(resource: URI, viewType: string): Promise<NotebookData> {
|
|
92
|
+
if (resource.scheme === 'untitled') {
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
cells: [
|
|
96
|
+
{
|
|
97
|
+
cellKind: CellKind.Markup,
|
|
98
|
+
language: 'markdown',
|
|
99
|
+
outputs: [],
|
|
100
|
+
source: ''
|
|
101
|
+
}
|
|
102
|
+
],
|
|
103
|
+
metadata: {}
|
|
104
|
+
};
|
|
105
|
+
} else {
|
|
106
|
+
const file = await this.fileService.readFile(resource);
|
|
107
|
+
|
|
108
|
+
const dataProvider = await this.notebookService.getNotebookDataProvider(viewType);
|
|
109
|
+
const notebook = await dataProvider.serializer.dataToNotebook(file.value);
|
|
110
|
+
|
|
111
|
+
return notebook;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
protected getPossibleFileEndings(selectors: readonly NotebookFileSelector[]): string | undefined {
|
|
116
|
+
for (const selector of selectors) {
|
|
117
|
+
const ending = this.possibleFileEnding(selector);
|
|
118
|
+
if (ending) {
|
|
119
|
+
return ending;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
protected possibleFileEnding(selector: NotebookFileSelector): string | undefined {
|
|
126
|
+
|
|
127
|
+
const pattern = /^.*(\.[a-zA-Z0-9_-]+)$/;
|
|
128
|
+
|
|
129
|
+
const candidate: string | undefined = typeof selector === 'string' ? selector : selector.filenamePattern;
|
|
130
|
+
|
|
131
|
+
if (candidate) {
|
|
132
|
+
const match = pattern.exec(candidate);
|
|
133
|
+
if (match) {
|
|
134
|
+
return match[1];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2023 TypeFox and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
/*---------------------------------------------------------------------------------------------
|
|
17
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
18
|
+
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
19
|
+
*--------------------------------------------------------------------------------------------*/
|
|
20
|
+
|
|
21
|
+
import { Emitter } from '@theia/core';
|
|
22
|
+
import { injectable } from '@theia/core/shared/inversify';
|
|
23
|
+
import { Disposable } from '@theia/core/shared/vscode-languageserver-protocol';
|
|
24
|
+
|
|
25
|
+
interface MessageToSend {
|
|
26
|
+
editorId: string;
|
|
27
|
+
rendererId: string;
|
|
28
|
+
message: unknown
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export interface ScopedRendererMessaging extends Disposable {
|
|
32
|
+
/**
|
|
33
|
+
* Method called when a message is received. Should return a boolean
|
|
34
|
+
* indicating whether a renderer received it.
|
|
35
|
+
*/
|
|
36
|
+
receiveMessageHandler?: (rendererId: string, message: unknown) => Promise<boolean>;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Sends a message to an extension from a renderer.
|
|
40
|
+
*/
|
|
41
|
+
postMessage(rendererId: string, message: unknown): void;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@injectable()
|
|
45
|
+
export class NotebookRendererMessagingService implements Disposable {
|
|
46
|
+
|
|
47
|
+
private readonly postMessageEmitter = new Emitter<MessageToSend>();
|
|
48
|
+
readonly onShouldPostMessage = this.postMessageEmitter.event;
|
|
49
|
+
|
|
50
|
+
private readonly activations = new Map<string /* rendererId */, undefined | MessageToSend[]>();
|
|
51
|
+
private readonly scopedMessaging = new Map<string /* editorId */, ScopedRendererMessaging>();
|
|
52
|
+
|
|
53
|
+
receiveMessage(editorId: string | undefined, rendererId: string, message: unknown): Promise<boolean> {
|
|
54
|
+
if (editorId === undefined) {
|
|
55
|
+
const sends = [...this.scopedMessaging.values()].map(e => e.receiveMessageHandler?.(rendererId, message));
|
|
56
|
+
return Promise.all(sends).then(values => values.some(value => !!value));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return this.scopedMessaging.get(editorId)?.receiveMessageHandler?.(rendererId, message) ?? Promise.resolve(false);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
prepare(rendererId: string): void {
|
|
63
|
+
if (this.activations.has(rendererId)) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const queue: MessageToSend[] = [];
|
|
68
|
+
this.activations.set(rendererId, queue);
|
|
69
|
+
|
|
70
|
+
// activate renderer
|
|
71
|
+
// this.extensionService.activateByEvent(`onRenderer:${rendererId}`).then(() => {
|
|
72
|
+
// for (const message of queue) {
|
|
73
|
+
// this.postMessageEmitter.fire(message);
|
|
74
|
+
// }
|
|
75
|
+
// this.activations.set(rendererId, undefined);
|
|
76
|
+
// });
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public getScoped(editorId: string): ScopedRendererMessaging {
|
|
80
|
+
const existing = this.scopedMessaging.get(editorId);
|
|
81
|
+
if (existing) {
|
|
82
|
+
return existing;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const messaging: ScopedRendererMessaging = {
|
|
86
|
+
postMessage: (rendererId, message) => this.postMessage(editorId, rendererId, message),
|
|
87
|
+
dispose: () => this.scopedMessaging.delete(editorId),
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
this.scopedMessaging.set(editorId, messaging);
|
|
91
|
+
return messaging;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
private postMessage(editorId: string, rendererId: string, message: unknown): void {
|
|
95
|
+
if (!this.activations.has(rendererId)) {
|
|
96
|
+
this.prepare(rendererId);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const activation = this.activations.get(rendererId);
|
|
100
|
+
const toSend = { rendererId, editorId, message };
|
|
101
|
+
if (activation === undefined) {
|
|
102
|
+
this.postMessageEmitter.fire(toSend);
|
|
103
|
+
} else {
|
|
104
|
+
activation.push(toSend);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
dispose(): void {
|
|
109
|
+
this.postMessageEmitter.dispose();
|
|
110
|
+
}
|
|
111
|
+
}
|