@theia/plugin-ext 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/common/plugin-api-rpc.d.ts +13 -2
- package/lib/common/plugin-api-rpc.d.ts.map +1 -1
- package/lib/common/plugin-api-rpc.js +12 -1
- package/lib/common/plugin-api-rpc.js.map +1 -1
- package/lib/common/proxy-handler.d.ts.map +1 -1
- package/lib/common/proxy-handler.js +3 -1
- package/lib/common/proxy-handler.js.map +1 -1
- package/lib/common/test-types.d.ts +1 -0
- package/lib/common/test-types.d.ts.map +1 -1
- package/lib/common/test-types.js.map +1 -1
- package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/browser/hosted-plugin.js +2 -0
- package/lib/hosted/browser/hosted-plugin.js.map +1 -1
- package/lib/hosted/browser/worker/worker-env-ext.d.ts +0 -3
- package/lib/hosted/browser/worker/worker-env-ext.d.ts.map +1 -1
- package/lib/hosted/browser/worker/worker-env-ext.js +2 -4
- package/lib/hosted/browser/worker/worker-env-ext.js.map +1 -1
- package/lib/main/browser/documents-main.d.ts +2 -4
- package/lib/main/browser/documents-main.d.ts.map +1 -1
- package/lib/main/browser/documents-main.js +2 -18
- package/lib/main/browser/documents-main.js.map +1 -1
- package/lib/main/browser/editors-and-documents-main.d.ts +2 -1
- package/lib/main/browser/editors-and-documents-main.d.ts.map +1 -1
- package/lib/main/browser/editors-and-documents-main.js +12 -5
- package/lib/main/browser/editors-and-documents-main.js.map +1 -1
- package/lib/main/browser/main-context.d.ts.map +1 -1
- package/lib/main/browser/main-context.js +4 -6
- package/lib/main/browser/main-context.js.map +1 -1
- package/lib/main/browser/notebooks/renderers/cell-output-webview.d.ts +7 -0
- package/lib/main/browser/notebooks/renderers/cell-output-webview.d.ts.map +1 -1
- package/lib/main/browser/notebooks/renderers/cell-output-webview.js +30 -4
- package/lib/main/browser/notebooks/renderers/cell-output-webview.js.map +1 -1
- package/lib/main/browser/notebooks/renderers/output-webview-internal.d.ts.map +1 -1
- package/lib/main/browser/notebooks/renderers/output-webview-internal.js +15 -0
- package/lib/main/browser/notebooks/renderers/output-webview-internal.js.map +1 -1
- package/lib/main/browser/notebooks/renderers/webview-communication.d.ts +5 -1
- package/lib/main/browser/notebooks/renderers/webview-communication.d.ts.map +1 -1
- package/lib/main/browser/tabs/tabs-main.d.ts +5 -3
- package/lib/main/browser/tabs/tabs-main.d.ts.map +1 -1
- package/lib/main/browser/tabs/tabs-main.js +37 -13
- package/lib/main/browser/tabs/tabs-main.js.map +1 -1
- package/lib/main/browser/test-main.d.ts +3 -2
- package/lib/main/browser/test-main.d.ts.map +1 -1
- package/lib/main/browser/test-main.js +7 -3
- package/lib/main/browser/test-main.js.map +1 -1
- package/lib/main/browser/text-editor-model-service.d.ts +1 -0
- package/lib/main/browser/text-editor-model-service.d.ts.map +1 -1
- package/lib/main/browser/text-editor-model-service.js +8 -0
- package/lib/main/browser/text-editor-model-service.js.map +1 -1
- package/lib/main/browser/view/tree-views-main.d.ts +0 -1
- package/lib/main/browser/view/tree-views-main.d.ts.map +1 -1
- package/lib/main/browser/view/tree-views-main.js +0 -3
- package/lib/main/browser/view/tree-views-main.js.map +1 -1
- package/lib/main/browser/view/view-context-key-service.d.ts +0 -2
- package/lib/main/browser/view/view-context-key-service.d.ts.map +1 -1
- package/lib/main/browser/view/view-context-key-service.js +0 -4
- package/lib/main/browser/view/view-context-key-service.js.map +1 -1
- package/lib/main/browser/window-state-main.js +1 -1
- package/lib/main/browser/window-state-main.js.map +1 -1
- package/lib/plugin/plugin-context.d.ts.map +1 -1
- package/lib/plugin/plugin-context.js +42 -2
- package/lib/plugin/plugin-context.js.map +1 -1
- package/lib/plugin/plugin-manager.d.ts +3 -1
- package/lib/plugin/plugin-manager.d.ts.map +1 -1
- package/lib/plugin/plugin-manager.js +13 -1
- package/lib/plugin/plugin-manager.js.map +1 -1
- package/lib/plugin/tests.d.ts +2 -2
- package/lib/plugin/tests.d.ts.map +1 -1
- package/lib/plugin/tests.js +12 -13
- package/lib/plugin/tests.js.map +1 -1
- package/lib/plugin/types-impl.d.ts +84 -1
- package/lib/plugin/types-impl.d.ts.map +1 -1
- package/lib/plugin/types-impl.js +106 -4
- package/lib/plugin/types-impl.js.map +1 -1
- package/package.json +29 -29
- package/src/common/plugin-api-rpc.ts +15 -2
- package/src/common/proxy-handler.ts +3 -1
- package/src/common/test-types.ts +1 -0
- package/src/hosted/browser/hosted-plugin.ts +3 -1
- package/src/hosted/browser/worker/worker-env-ext.ts +2 -4
- package/src/main/browser/documents-main.ts +3 -21
- package/src/main/browser/editors-and-documents-main.ts +13 -5
- package/src/main/browser/main-context.ts +5 -7
- package/src/main/browser/notebooks/renderers/cell-output-webview.tsx +33 -4
- package/src/main/browser/notebooks/renderers/output-webview-internal.ts +18 -0
- package/src/main/browser/notebooks/renderers/webview-communication.ts +12 -1
- package/src/main/browser/tabs/tabs-main.ts +39 -15
- package/src/main/browser/test-main.ts +8 -3
- package/src/main/browser/text-editor-model-service.ts +9 -0
- package/src/main/browser/view/tree-views-main.ts +0 -4
- package/src/main/browser/view/view-context-key-service.ts +0 -6
- package/src/main/browser/window-state-main.ts +1 -1
- package/src/plugin/plugin-context.ts +59 -4
- package/src/plugin/plugin-manager.ts +17 -3
- package/src/plugin/tests.ts +14 -14
- package/src/plugin/types-impl.ts +121 -0
|
@@ -20,10 +20,10 @@ import { DisposableCollection, Disposable, UntitledResourceResolver } from '@the
|
|
|
20
20
|
import { MonacoEditorModel } from '@theia/monaco/lib/browser/monaco-editor-model';
|
|
21
21
|
import { RPCProtocol } from '../../common/rpc-protocol';
|
|
22
22
|
import { EditorModelService } from './text-editor-model-service';
|
|
23
|
-
import {
|
|
23
|
+
import { EditorOpenerOptions } from '@theia/editor/lib/browser';
|
|
24
24
|
import URI from '@theia/core/lib/common/uri';
|
|
25
25
|
import { URI as CodeURI } from '@theia/core/shared/vscode-uri';
|
|
26
|
-
import { ApplicationShell
|
|
26
|
+
import { ApplicationShell } from '@theia/core/lib/browser';
|
|
27
27
|
import { TextDocumentShowOptions } from '../../common/plugin-api-rpc-model';
|
|
28
28
|
import { Range } from '@theia/core/shared/vscode-languageserver-protocol';
|
|
29
29
|
import { OpenerService } from '@theia/core/lib/browser/opener-service';
|
|
@@ -94,7 +94,6 @@ export class DocumentsMainImpl implements DocumentsMain, Disposable {
|
|
|
94
94
|
notebookDocuments: NotebookDocumentsMainImpl,
|
|
95
95
|
private readonly modelService: EditorModelService,
|
|
96
96
|
rpc: RPCProtocol,
|
|
97
|
-
private editorManager: EditorManager,
|
|
98
97
|
private openerService: OpenerService,
|
|
99
98
|
private shell: ApplicationShell,
|
|
100
99
|
private untitledResourceResolver: UntitledResourceResolver,
|
|
@@ -206,13 +205,7 @@ export class DocumentsMainImpl implements DocumentsMain, Disposable {
|
|
|
206
205
|
}
|
|
207
206
|
|
|
208
207
|
async $trySaveDocument(uri: UriComponents): Promise<boolean> {
|
|
209
|
-
|
|
210
|
-
if (widget) {
|
|
211
|
-
await Saveable.save(widget);
|
|
212
|
-
return true;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
return false;
|
|
208
|
+
return this.modelService.save(new URI(CodeURI.revive(uri)));
|
|
216
209
|
}
|
|
217
210
|
|
|
218
211
|
async $tryOpenDocument(uri: UriComponents): Promise<boolean> {
|
|
@@ -226,17 +219,6 @@ export class DocumentsMainImpl implements DocumentsMain, Disposable {
|
|
|
226
219
|
}
|
|
227
220
|
}
|
|
228
221
|
|
|
229
|
-
async $tryCloseDocument(uri: UriComponents): Promise<boolean> {
|
|
230
|
-
const widget = await this.editorManager.getByUri(new URI(CodeURI.revive(uri)));
|
|
231
|
-
if (widget) {
|
|
232
|
-
await Saveable.save(widget);
|
|
233
|
-
widget.close();
|
|
234
|
-
return true;
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
return false;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
222
|
static toEditorOpenerOptions(shell: ApplicationShell, options?: TextDocumentShowOptions): EditorOpenerOptions | undefined {
|
|
241
223
|
if (!options) {
|
|
242
224
|
return undefined;
|
|
@@ -33,6 +33,7 @@ import { TextEditorMain } from './text-editor-main';
|
|
|
33
33
|
import { DisposableCollection, Emitter, URI } from '@theia/core';
|
|
34
34
|
import { EditorManager, EditorWidget } from '@theia/editor/lib/browser';
|
|
35
35
|
import { SaveableService } from '@theia/core/lib/browser/saveable-service';
|
|
36
|
+
import { TabsMainImpl } from './tabs/tabs-main';
|
|
36
37
|
|
|
37
38
|
export class EditorsAndDocumentsMain implements Disposable {
|
|
38
39
|
|
|
@@ -59,14 +60,14 @@ export class EditorsAndDocumentsMain implements Disposable {
|
|
|
59
60
|
Disposable.create(() => this.textEditors.clear())
|
|
60
61
|
);
|
|
61
62
|
|
|
62
|
-
constructor(rpc: RPCProtocol, container: interfaces.Container) {
|
|
63
|
+
constructor(rpc: RPCProtocol, container: interfaces.Container, tabsMain: TabsMainImpl) {
|
|
63
64
|
this.proxy = rpc.getProxy(MAIN_RPC_CONTEXT.EDITORS_AND_DOCUMENTS_EXT);
|
|
64
65
|
|
|
65
66
|
this.editorManager = container.get(EditorManager);
|
|
66
67
|
this.modelService = container.get(EditorModelService);
|
|
67
68
|
this.saveResourceService = container.get(SaveableService);
|
|
68
69
|
|
|
69
|
-
this.stateComputer = new EditorAndDocumentStateComputer(d => this.onDelta(d), this.editorManager, this.modelService);
|
|
70
|
+
this.stateComputer = new EditorAndDocumentStateComputer(d => this.onDelta(d), this.editorManager, this.modelService, tabsMain);
|
|
70
71
|
this.toDispose.push(this.stateComputer);
|
|
71
72
|
this.toDispose.push(this.onTextEditorAddEmitter);
|
|
72
73
|
this.toDispose.push(this.onTextEditorRemoveEmitter);
|
|
@@ -217,18 +218,25 @@ class EditorAndDocumentStateComputer implements Disposable {
|
|
|
217
218
|
constructor(
|
|
218
219
|
private callback: (delta: EditorAndDocumentStateDelta) => void,
|
|
219
220
|
private readonly editorService: EditorManager,
|
|
220
|
-
private readonly modelService: EditorModelService
|
|
221
|
+
private readonly modelService: EditorModelService,
|
|
222
|
+
private readonly tabsMain: TabsMainImpl
|
|
221
223
|
) { }
|
|
222
224
|
|
|
223
225
|
listen(): void {
|
|
224
226
|
if (this.toDispose.disposed) {
|
|
225
227
|
return;
|
|
226
228
|
}
|
|
227
|
-
this.toDispose.push(this.editorService.onCreated(widget => {
|
|
229
|
+
this.toDispose.push(this.editorService.onCreated(async widget => {
|
|
230
|
+
await this.tabsMain.waitForWidget(widget);
|
|
228
231
|
this.onTextEditorAdd(widget);
|
|
229
232
|
this.update();
|
|
230
233
|
}));
|
|
231
|
-
this.toDispose.push(this.editorService.onCurrentEditorChanged(
|
|
234
|
+
this.toDispose.push(this.editorService.onCurrentEditorChanged(async widget => {
|
|
235
|
+
if (widget) {
|
|
236
|
+
await this.tabsMain.waitForWidget(widget);
|
|
237
|
+
}
|
|
238
|
+
this.update();
|
|
239
|
+
}));
|
|
232
240
|
this.toDispose.push(this.modelService.onModelAdded(this.onModelAdded, this));
|
|
233
241
|
this.toDispose.push(this.modelService.onModelRemoved(() => this.update()));
|
|
234
242
|
|
|
@@ -40,7 +40,6 @@ import { DecorationsMainImpl } from './decorations/decorations-main';
|
|
|
40
40
|
import { ClipboardMainImpl } from './clipboard-main';
|
|
41
41
|
import { DocumentsMainImpl } from './documents-main';
|
|
42
42
|
import { TextEditorsMainImpl } from './text-editors-main';
|
|
43
|
-
import { EditorManager } from '@theia/editor/lib/browser';
|
|
44
43
|
import { EditorModelService } from './text-editor-model-service';
|
|
45
44
|
import { OpenerService } from '@theia/core/lib/browser/opener-service';
|
|
46
45
|
import { ApplicationShell } from '@theia/core/lib/browser/shell/application-shell';
|
|
@@ -88,19 +87,21 @@ export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container
|
|
|
88
87
|
const preferenceRegistryMain = new PreferenceRegistryMainImpl(rpc, container);
|
|
89
88
|
rpc.set(PLUGIN_RPC_CONTEXT.PREFERENCE_REGISTRY_MAIN, preferenceRegistryMain);
|
|
90
89
|
|
|
91
|
-
const
|
|
90
|
+
const tabsMain = new TabsMainImpl(rpc, container);
|
|
91
|
+
rpc.set(PLUGIN_RPC_CONTEXT.TABS_MAIN, tabsMain);
|
|
92
|
+
|
|
93
|
+
const editorsAndDocuments = new EditorsAndDocumentsMain(rpc, container, tabsMain);
|
|
92
94
|
|
|
93
95
|
const notebookDocumentsMain = new NotebookDocumentsMainImpl(rpc, container);
|
|
94
96
|
rpc.set(PLUGIN_RPC_CONTEXT.NOTEBOOK_DOCUMENTS_MAIN, notebookDocumentsMain);
|
|
95
97
|
|
|
96
98
|
const modelService = container.get(EditorModelService);
|
|
97
|
-
const editorManager = container.get(EditorManager);
|
|
98
99
|
const openerService = container.get<OpenerService>(OpenerService);
|
|
99
100
|
const shell = container.get(ApplicationShell);
|
|
100
101
|
const untitledResourceResolver = container.get(UntitledResourceResolver);
|
|
101
102
|
const languageService = container.get(MonacoLanguages);
|
|
102
103
|
const documentsMain = new DocumentsMainImpl(editorsAndDocuments, notebookDocumentsMain, modelService, rpc,
|
|
103
|
-
|
|
104
|
+
openerService, shell, untitledResourceResolver, languageService);
|
|
104
105
|
rpc.set(PLUGIN_RPC_CONTEXT.DOCUMENTS_MAIN, documentsMain);
|
|
105
106
|
|
|
106
107
|
rpc.set(PLUGIN_RPC_CONTEXT.NOTEBOOKS_MAIN, new NotebooksMainImpl(rpc, container, commandRegistryMain));
|
|
@@ -200,9 +201,6 @@ export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container
|
|
|
200
201
|
const commentsMain = new CommentsMainImp(rpc, container);
|
|
201
202
|
rpc.set(PLUGIN_RPC_CONTEXT.COMMENTS_MAIN, commentsMain);
|
|
202
203
|
|
|
203
|
-
const tabsMain = new TabsMainImpl(rpc, container);
|
|
204
|
-
rpc.set(PLUGIN_RPC_CONTEXT.TABS_MAIN, tabsMain);
|
|
205
|
-
|
|
206
204
|
const localizationMain = new LocalizationMainImpl(container);
|
|
207
205
|
rpc.set(PLUGIN_RPC_CONTEXT.LOCALIZATION_MAIN, localizationMain);
|
|
208
206
|
}
|
|
@@ -35,6 +35,7 @@ import { CellUri } from '@theia/notebook/lib/common';
|
|
|
35
35
|
import { Disposable, DisposableCollection, nls, QuickPickService } from '@theia/core';
|
|
36
36
|
import { NotebookCellOutputModel } from '@theia/notebook/lib/browser/view-model/notebook-cell-output-model';
|
|
37
37
|
import { NotebookModel } from '@theia/notebook/lib/browser/view-model/notebook-model';
|
|
38
|
+
import { NotebookOptionsService, NotebookOutputOptions } from '@theia/notebook/lib/browser/service/notebook-options';
|
|
38
39
|
|
|
39
40
|
const CellModel = Symbol('CellModel');
|
|
40
41
|
const Notebook = Symbol('NotebookModel');
|
|
@@ -147,6 +148,11 @@ export class CellOutputWebviewImpl implements CellOutputWebview, Disposable {
|
|
|
147
148
|
@inject(AdditionalNotebookCellOutputCss)
|
|
148
149
|
protected readonly additionalOutputCss: string;
|
|
149
150
|
|
|
151
|
+
@inject(NotebookOptionsService)
|
|
152
|
+
protected readonly notebookOptionsService: NotebookOptionsService;
|
|
153
|
+
|
|
154
|
+
protected options: NotebookOutputOptions;
|
|
155
|
+
|
|
150
156
|
readonly id = generateUuid();
|
|
151
157
|
|
|
152
158
|
protected editor: NotebookEditorWidget | undefined;
|
|
@@ -161,6 +167,11 @@ export class CellOutputWebviewImpl implements CellOutputWebview, Disposable {
|
|
|
161
167
|
@postConstruct()
|
|
162
168
|
protected async init(): Promise<void> {
|
|
163
169
|
this.editor = this.notebookEditorWidgetService.getNotebookEditor(NOTEBOOK_EDITOR_ID_PREFIX + CellUri.parse(this.cell.uri)?.notebook);
|
|
170
|
+
this.options = this.notebookOptionsService.computeOutputOptions();
|
|
171
|
+
this.toDispose.push(this.notebookOptionsService.onDidChangeOutputOptions(options => {
|
|
172
|
+
this.options = options;
|
|
173
|
+
this.updateStyles();
|
|
174
|
+
}));
|
|
164
175
|
|
|
165
176
|
this.toDispose.push(this.cell.onDidChangeOutputs(outputChange => this.updateOutput(outputChange)));
|
|
166
177
|
this.toDispose.push(this.cell.onDidChangeOutputItems(output => {
|
|
@@ -187,6 +198,7 @@ export class CellOutputWebviewImpl implements CellOutputWebview, Disposable {
|
|
|
187
198
|
}
|
|
188
199
|
|
|
189
200
|
this.webviewWidget = await this.widgetManager.getOrCreateWidget(WebviewWidget.FACTORY_ID, { id: this.id });
|
|
201
|
+
this.webviewWidget.parent = this.editor ?? null;
|
|
190
202
|
this.webviewWidget.setContentOptions({
|
|
191
203
|
allowScripts: true,
|
|
192
204
|
// eslint-disable-next-line max-len
|
|
@@ -271,6 +283,7 @@ export class CellOutputWebviewImpl implements CellOutputWebview, Disposable {
|
|
|
271
283
|
switch (message.type) {
|
|
272
284
|
case 'initialized':
|
|
273
285
|
this.updateOutput({ newOutputs: this.cell.outputs, start: 0, deleteCount: 0 });
|
|
286
|
+
this.updateStyles();
|
|
274
287
|
break;
|
|
275
288
|
case 'customRendererMessage':
|
|
276
289
|
// console.log('from webview customRendererMessage ', message.rendererId, '', JSON.stringify(message.message));
|
|
@@ -301,6 +314,22 @@ export class CellOutputWebviewImpl implements CellOutputWebview, Disposable {
|
|
|
301
314
|
return kernelPreloads.concat(staticPreloads);
|
|
302
315
|
}
|
|
303
316
|
|
|
317
|
+
protected updateStyles(): void {
|
|
318
|
+
this.webviewWidget.sendMessage({
|
|
319
|
+
type: 'notebookStyles',
|
|
320
|
+
styles: this.generateStyles()
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
protected generateStyles(): { [key: string]: string } {
|
|
325
|
+
return {
|
|
326
|
+
'notebook-cell-output-font-size': `${this.options.outputFontSize || this.options.fontSize}px`,
|
|
327
|
+
'notebook-cell-output-line-height': `${this.options.outputLineHeight}px`,
|
|
328
|
+
'notebook-cell-output-max-height': `${this.options.outputLineHeight * this.options.outputLineLimit}px`,
|
|
329
|
+
'notebook-cell-output-font-family': this.options.outputFontFamily || this.options.fontFamily,
|
|
330
|
+
};
|
|
331
|
+
}
|
|
332
|
+
|
|
304
333
|
private async createWebviewContent(): Promise<string> {
|
|
305
334
|
const isWorkspaceTrusted = await this.workspaceTrustService.getWorkspaceTrust();
|
|
306
335
|
const preloads = this.preloadsScriptString(isWorkspaceTrusted);
|
|
@@ -324,10 +353,10 @@ export class CellOutputWebviewImpl implements CellOutputWebview, Disposable {
|
|
|
324
353
|
const ctx: PreloadContext = {
|
|
325
354
|
isWorkspaceTrusted,
|
|
326
355
|
rendererData: this.notebookRendererRegistry.notebookRenderers,
|
|
327
|
-
renderOptions: {
|
|
328
|
-
lineLimit:
|
|
329
|
-
outputScrolling:
|
|
330
|
-
outputWordWrap:
|
|
356
|
+
renderOptions: {
|
|
357
|
+
lineLimit: this.options.outputLineLimit,
|
|
358
|
+
outputScrolling: this.options.outputScrolling,
|
|
359
|
+
outputWordWrap: this.options.outputWordWrap,
|
|
331
360
|
},
|
|
332
361
|
staticPreloadsData: this.getPreloads()
|
|
333
362
|
};
|
|
@@ -569,6 +569,24 @@ export async function outputWebviewPreload(ctx: PreloadContext): Promise<void> {
|
|
|
569
569
|
}
|
|
570
570
|
break;
|
|
571
571
|
}
|
|
572
|
+
case 'notebookStyles': {
|
|
573
|
+
const documentStyle = window.document.documentElement.style;
|
|
574
|
+
|
|
575
|
+
for (let i = documentStyle.length - 1; i >= 0; i--) {
|
|
576
|
+
const property = documentStyle[i];
|
|
577
|
+
|
|
578
|
+
// Don't remove properties that the webview might have added separately
|
|
579
|
+
if (property && property.startsWith('--notebook-')) {
|
|
580
|
+
documentStyle.removeProperty(property);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// Re-add new properties
|
|
585
|
+
for (const [name, value] of Object.entries(event.data.styles)) {
|
|
586
|
+
documentStyle.setProperty(`--${name}`, value);
|
|
587
|
+
}
|
|
588
|
+
break;
|
|
589
|
+
}
|
|
572
590
|
}
|
|
573
591
|
});
|
|
574
592
|
window.addEventListener('wheel', handleWheel);
|
|
@@ -59,7 +59,18 @@ export interface PreloadMessage {
|
|
|
59
59
|
readonly resources: string[];
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
export
|
|
62
|
+
export interface notebookStylesMessage {
|
|
63
|
+
readonly type: 'notebookStyles';
|
|
64
|
+
styles: Record<string, string>;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export type ToWebviewMessage = UpdateRenderersMessage
|
|
68
|
+
| OutputChangedMessage
|
|
69
|
+
| ChangePreferredMimetypeMessage
|
|
70
|
+
| CustomRendererMessage
|
|
71
|
+
| KernelMessage
|
|
72
|
+
| PreloadMessage
|
|
73
|
+
| notebookStylesMessage;
|
|
63
74
|
|
|
64
75
|
export interface WebviewInitialized {
|
|
65
76
|
readonly type: 'initialized';
|
|
@@ -25,7 +25,7 @@ import { toUriComponents } from '../hierarchy/hierarchy-types-converters';
|
|
|
25
25
|
import { TerminalWidget } from '@theia/terminal/lib/browser/base/terminal-widget';
|
|
26
26
|
import { DisposableCollection } from '@theia/core';
|
|
27
27
|
import { NotebookEditorWidget } from '@theia/notebook/lib/browser';
|
|
28
|
-
import {
|
|
28
|
+
import { Deferred } from '@theia/core/lib/common/promise-util';
|
|
29
29
|
|
|
30
30
|
interface TabInfo {
|
|
31
31
|
tab: TabDto;
|
|
@@ -38,17 +38,17 @@ export class TabsMainImpl implements TabsMain, Disposable {
|
|
|
38
38
|
private readonly proxy: TabsExt;
|
|
39
39
|
private tabGroupModel = new Map<TabBar<Widget>, TabGroupDto>();
|
|
40
40
|
private tabInfoLookup = new Map<Title<Widget>, TabInfo>();
|
|
41
|
+
private waitQueue = new Map<Widget, Deferred>();
|
|
41
42
|
|
|
42
43
|
private applicationShell: ApplicationShell;
|
|
43
44
|
|
|
44
45
|
private disposableTabBarListeners: DisposableCollection = new DisposableCollection();
|
|
45
46
|
private toDisposeOnDestroy: DisposableCollection = new DisposableCollection();
|
|
46
47
|
|
|
47
|
-
private groupIdCounter =
|
|
48
|
+
private groupIdCounter = 1;
|
|
48
49
|
private currentActiveGroup: TabGroupDto;
|
|
49
50
|
|
|
50
51
|
private tabGroupChanged: boolean = false;
|
|
51
|
-
private viewColumnService: ViewColumnService;
|
|
52
52
|
|
|
53
53
|
private readonly defaultTabGroup: TabGroupDto = {
|
|
54
54
|
groupId: 0,
|
|
@@ -64,11 +64,10 @@ export class TabsMainImpl implements TabsMain, Disposable {
|
|
|
64
64
|
this.proxy = rpc.getProxy(MAIN_RPC_CONTEXT.TABS_EXT);
|
|
65
65
|
|
|
66
66
|
this.applicationShell = container.get(ApplicationShell);
|
|
67
|
-
this.viewColumnService = container.get(ViewColumnService);
|
|
68
67
|
this.createTabsModel();
|
|
69
68
|
|
|
70
69
|
const tabBars = this.applicationShell.mainPanel.tabBars();
|
|
71
|
-
for (let tabBar; tabBar = tabBars.next();) {
|
|
70
|
+
for (let tabBar: TabBar<Widget> | undefined; tabBar = tabBars.next();) {
|
|
72
71
|
this.attachListenersToTabBar(tabBar);
|
|
73
72
|
}
|
|
74
73
|
|
|
@@ -110,6 +109,21 @@ export class TabsMainImpl implements TabsMain, Disposable {
|
|
|
110
109
|
});
|
|
111
110
|
}
|
|
112
111
|
|
|
112
|
+
waitForWidget(widget: Widget): Promise<void> {
|
|
113
|
+
const deferred = new Deferred<void>();
|
|
114
|
+
this.waitQueue.set(widget, deferred);
|
|
115
|
+
|
|
116
|
+
const timeout = setTimeout(() => {
|
|
117
|
+
deferred.resolve(); // resolve to unblock the event
|
|
118
|
+
}, 1000);
|
|
119
|
+
|
|
120
|
+
deferred.promise.then(() => {
|
|
121
|
+
clearTimeout(timeout);
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
return deferred.promise;
|
|
125
|
+
}
|
|
126
|
+
|
|
113
127
|
protected createTabsModel(): void {
|
|
114
128
|
if (this.applicationShell.mainAreaTabBars.length === 0) {
|
|
115
129
|
this.proxy.$acceptEditorTabModel([this.defaultTabGroup]);
|
|
@@ -119,9 +133,9 @@ export class TabsMainImpl implements TabsMain, Disposable {
|
|
|
119
133
|
this.tabInfoLookup.clear();
|
|
120
134
|
this.disposableTabBarListeners.dispose();
|
|
121
135
|
this.applicationShell.mainAreaTabBars
|
|
122
|
-
.forEach(
|
|
136
|
+
.forEach(tabBar => {
|
|
123
137
|
this.attachListenersToTabBar(tabBar);
|
|
124
|
-
const groupDto = this.createTabGroupDto(tabBar
|
|
138
|
+
const groupDto = this.createTabGroupDto(tabBar);
|
|
125
139
|
tabBar.titles.forEach((title, index) => this.tabInfoLookup.set(title, { group: groupDto, tab: groupDto.tabs[index], tabIndex: index }));
|
|
126
140
|
newTabGroupModel.set(tabBar, groupDto);
|
|
127
141
|
});
|
|
@@ -131,31 +145,38 @@ export class TabsMainImpl implements TabsMain, Disposable {
|
|
|
131
145
|
}
|
|
132
146
|
this.tabGroupModel = newTabGroupModel;
|
|
133
147
|
this.proxy.$acceptEditorTabModel(Array.from(this.tabGroupModel.values()));
|
|
148
|
+
// Resolve all waiting widget promises
|
|
149
|
+
this.waitQueue.forEach(deferred => deferred.resolve());
|
|
150
|
+
this.waitQueue.clear();
|
|
134
151
|
}
|
|
135
152
|
|
|
136
|
-
protected createTabDto(tabTitle: Title<Widget>, groupId: number): TabDto {
|
|
153
|
+
protected createTabDto(tabTitle: Title<Widget>, groupId: number, newTab = false): TabDto {
|
|
137
154
|
const widget = tabTitle.owner;
|
|
155
|
+
const active = newTab || this.getTabBar(tabTitle)?.currentTitle === tabTitle;
|
|
138
156
|
return {
|
|
139
157
|
id: this.createTabId(tabTitle, groupId),
|
|
140
158
|
label: tabTitle.label,
|
|
141
159
|
input: this.evaluateTabDtoInput(widget),
|
|
142
|
-
isActive:
|
|
160
|
+
isActive: active,
|
|
143
161
|
isPinned: tabTitle.className.includes(PINNED_CLASS),
|
|
144
162
|
isDirty: Saveable.isDirty(widget),
|
|
145
163
|
isPreview: widget instanceof EditorPreviewWidget && widget.isPreview
|
|
146
164
|
};
|
|
147
165
|
}
|
|
148
166
|
|
|
167
|
+
protected getTabBar(tabTitle: Title<Widget>): TabBar<Widget> | undefined {
|
|
168
|
+
return this.applicationShell.mainPanel.findTabBar(tabTitle);
|
|
169
|
+
}
|
|
170
|
+
|
|
149
171
|
protected createTabId(tabTitle: Title<Widget>, groupId: number): string {
|
|
150
172
|
return `${groupId}~${tabTitle.owner.id}`;
|
|
151
173
|
}
|
|
152
174
|
|
|
153
|
-
protected createTabGroupDto(tabBar: TabBar<Widget
|
|
154
|
-
const oldDto =
|
|
175
|
+
protected createTabGroupDto(tabBar: TabBar<Widget>): TabGroupDto {
|
|
176
|
+
const oldDto = this.tabGroupModel.get(tabBar);
|
|
155
177
|
const groupId = oldDto?.groupId ?? this.groupIdCounter++;
|
|
156
178
|
const tabs = tabBar.titles.map(title => this.createTabDto(title, groupId));
|
|
157
|
-
const viewColumn =
|
|
158
|
-
?? this.applicationShell.allTabBars.indexOf(tabBar);
|
|
179
|
+
const viewColumn = 0; // TODO: Implement correct viewColumn handling
|
|
159
180
|
return {
|
|
160
181
|
groupId,
|
|
161
182
|
tabs,
|
|
@@ -190,7 +211,6 @@ export class TabsMainImpl implements TabsMain, Disposable {
|
|
|
190
211
|
uri: toUriComponents(widget.editor.uri.toString())
|
|
191
212
|
};
|
|
192
213
|
}
|
|
193
|
-
// TODO notebook support when implemented
|
|
194
214
|
} else if (widget instanceof ViewContainer) {
|
|
195
215
|
return {
|
|
196
216
|
kind: TabInputKind.WebviewEditorInput,
|
|
@@ -238,7 +258,7 @@ export class TabsMainImpl implements TabsMain, Disposable {
|
|
|
238
258
|
private onTabCreated(tabBar: TabBar<Widget>, args: TabBar.ITabActivateRequestedArgs<Widget>): void {
|
|
239
259
|
const group = this.getOrRebuildModel(this.tabGroupModel, tabBar);
|
|
240
260
|
this.connectToSignal(this.disposableTabBarListeners, args.title.changed, this.onTabTitleChanged);
|
|
241
|
-
const tabDto = this.createTabDto(args.title, group.groupId);
|
|
261
|
+
const tabDto = this.createTabDto(args.title, group.groupId, true);
|
|
242
262
|
this.tabInfoLookup.set(args.title, { group, tab: tabDto, tabIndex: args.index });
|
|
243
263
|
group.tabs.splice(args.index, 0, tabDto);
|
|
244
264
|
this.proxy.$acceptTabOperation({
|
|
@@ -247,6 +267,8 @@ export class TabsMainImpl implements TabsMain, Disposable {
|
|
|
247
267
|
tabDto,
|
|
248
268
|
groupId: group.groupId
|
|
249
269
|
});
|
|
270
|
+
this.waitQueue.get(args.title.owner)?.resolve();
|
|
271
|
+
this.waitQueue.delete(args.title.owner);
|
|
250
272
|
}
|
|
251
273
|
|
|
252
274
|
private onTabTitleChanged(title: Title<Widget>): void {
|
|
@@ -275,6 +297,8 @@ export class TabsMainImpl implements TabsMain, Disposable {
|
|
|
275
297
|
groupId: tabInfo.group.groupId
|
|
276
298
|
});
|
|
277
299
|
}
|
|
300
|
+
this.waitQueue.get(title.owner)?.resolve();
|
|
301
|
+
this.waitQueue.delete(title.owner);
|
|
278
302
|
}
|
|
279
303
|
|
|
280
304
|
private onTabClosed(tabInfo: TabInfo, title: Title<Widget>): void {
|
|
@@ -18,6 +18,7 @@ import { SimpleObservableCollection, TreeCollection, observableProperty } from '
|
|
|
18
18
|
import {
|
|
19
19
|
TestController, TestItem, TestOutputItem, TestRun, TestRunProfile, TestService, TestState, TestStateChangedEvent
|
|
20
20
|
} from '@theia/test/lib/browser/test-service';
|
|
21
|
+
import { TestExecutionProgressService } from '@theia/test/lib/browser/test-execution-progress-service';
|
|
21
22
|
import { AccumulatingTreeDeltaEmitter, CollectionDelta, DeltaKind, TreeDelta, TreeDeltaBuilder } from '@theia/test/lib/common/tree-delta';
|
|
22
23
|
import { Emitter, Location, Range } from '@theia/core/shared/vscode-languageserver-protocol';
|
|
23
24
|
import { Range as PluginRange, Location as PluginLocation } from '../../common/plugin-api-rpc-model';
|
|
@@ -245,13 +246,14 @@ class TestRunProfileImpl implements TestRunProfile {
|
|
|
245
246
|
this.proxy.$onConfigureRunProfile(this.controllerId, this.id);
|
|
246
247
|
}
|
|
247
248
|
|
|
248
|
-
run(name: string, included: TestItem[], excluded: TestItem[]): void {
|
|
249
|
+
run(name: string, included: TestItem[], excluded: TestItem[], preserveFocus: boolean): void {
|
|
249
250
|
this.proxy.$onRunControllerTests([{
|
|
250
251
|
controllerId: this.controllerId,
|
|
251
252
|
name,
|
|
252
253
|
profileId: this.id,
|
|
253
254
|
includedTests: included.map(item => itemToPath(item)),
|
|
254
|
-
excludedTests: excluded.map(item => itemToPath(item))
|
|
255
|
+
excludedTests: excluded.map(item => itemToPath(item)),
|
|
256
|
+
preserveFocus
|
|
255
257
|
}]);
|
|
256
258
|
}
|
|
257
259
|
}
|
|
@@ -551,12 +553,14 @@ class TestControllerImpl implements TestController {
|
|
|
551
553
|
|
|
552
554
|
export class TestingMainImpl implements TestingMain {
|
|
553
555
|
private testService: TestService;
|
|
556
|
+
private testExecutionProgressService: TestExecutionProgressService;
|
|
554
557
|
private controllerRegistrations = new Map<string, [TestControllerImpl, Disposable]>();
|
|
555
558
|
private proxy: TestingExt;
|
|
556
559
|
canRefresh: boolean;
|
|
557
560
|
|
|
558
561
|
constructor(rpc: RPCProtocol, container: interfaces.Container, commandRegistry: CommandRegistryMainImpl) {
|
|
559
562
|
this.testService = container.get(TestService);
|
|
563
|
+
this.testExecutionProgressService = container.get(TestExecutionProgressService);
|
|
560
564
|
this.proxy = rpc.getProxy(MAIN_RPC_CONTEXT.TESTING_EXT);
|
|
561
565
|
commandRegistry.registerArgumentProcessor({
|
|
562
566
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -614,7 +618,8 @@ export class TestingMainImpl implements TestingMain {
|
|
|
614
618
|
$removeTestRunProfile(controllerId: string, profileId: string): void {
|
|
615
619
|
this.withController(controllerId).removeProfile(profileId);
|
|
616
620
|
}
|
|
617
|
-
$notifyTestRunCreated(controllerId: string, run: TestRunDTO): void {
|
|
621
|
+
$notifyTestRunCreated(controllerId: string, run: TestRunDTO, preserveFocus: boolean): void {
|
|
622
|
+
this.testExecutionProgressService.onTestRunRequested(preserveFocus);
|
|
618
623
|
this.withController(controllerId).addRun(run.id, run.name, run.isRunning);
|
|
619
624
|
}
|
|
620
625
|
$notifyTestStateChanged(controllerId: string, runId: string, stateChanges: TestStateChangeDTO[], outputChanges: TestOutputDTO[]): void {
|
|
@@ -76,6 +76,15 @@ export class EditorModelService {
|
|
|
76
76
|
return this.monacoModelService.models;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
async save(uri: URI): Promise<boolean> {
|
|
80
|
+
const model = this.monacoModelService.get(uri.toString());
|
|
81
|
+
if (model) {
|
|
82
|
+
await model.save();
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
79
88
|
async saveAll(includeUntitled?: boolean): Promise<boolean> {
|
|
80
89
|
const saves = [];
|
|
81
90
|
for (const model of this.monacoModelService.models) {
|
|
@@ -24,7 +24,6 @@ import {
|
|
|
24
24
|
CompositeTreeNode,
|
|
25
25
|
WidgetManager
|
|
26
26
|
} from '@theia/core/lib/browser';
|
|
27
|
-
import { ViewContextKeyService } from './view-context-key-service';
|
|
28
27
|
import { Disposable, DisposableCollection } from '@theia/core';
|
|
29
28
|
import { TreeViewWidget, TreeViewNode, PluginTreeModel, TreeViewWidgetOptions } from './tree-view-widget';
|
|
30
29
|
import { PluginViewWidget } from './plugin-view-widget';
|
|
@@ -36,7 +35,6 @@ export class TreeViewsMainImpl implements TreeViewsMain, Disposable {
|
|
|
36
35
|
|
|
37
36
|
private readonly proxy: TreeViewsExt;
|
|
38
37
|
private readonly viewRegistry: PluginViewRegistry;
|
|
39
|
-
private readonly contextKeys: ViewContextKeyService;
|
|
40
38
|
private readonly widgetManager: WidgetManager;
|
|
41
39
|
private readonly fileContentStore: DnDFileContentStore;
|
|
42
40
|
|
|
@@ -50,7 +48,6 @@ export class TreeViewsMainImpl implements TreeViewsMain, Disposable {
|
|
|
50
48
|
this.proxy = rpc.getProxy(MAIN_RPC_CONTEXT.TREE_VIEWS_EXT);
|
|
51
49
|
this.viewRegistry = container.get(PluginViewRegistry);
|
|
52
50
|
|
|
53
|
-
this.contextKeys = this.container.get(ViewContextKeyService);
|
|
54
51
|
this.widgetManager = this.container.get(WidgetManager);
|
|
55
52
|
this.fileContentStore = this.container.get(DnDFileContentStore);
|
|
56
53
|
}
|
|
@@ -197,7 +194,6 @@ export class TreeViewsMainImpl implements TreeViewsMain, Disposable {
|
|
|
197
194
|
}));
|
|
198
195
|
|
|
199
196
|
this.toDispose.push(treeViewWidget.model.onSelectionChanged(event => {
|
|
200
|
-
this.contextKeys.view.set(treeViewId);
|
|
201
197
|
this.proxy.$setSelection(treeViewId, event.map((node: TreeViewNode) => node.id));
|
|
202
198
|
}));
|
|
203
199
|
|
|
@@ -19,11 +19,6 @@ import { ContextKey, ContextKeyService } from '@theia/core/lib/browser/context-k
|
|
|
19
19
|
|
|
20
20
|
@injectable()
|
|
21
21
|
export class ViewContextKeyService {
|
|
22
|
-
protected _view: ContextKey<string>;
|
|
23
|
-
get view(): ContextKey<string> {
|
|
24
|
-
return this._view;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
22
|
protected _viewItem: ContextKey<string>;
|
|
28
23
|
get viewItem(): ContextKey<string> {
|
|
29
24
|
return this._viewItem;
|
|
@@ -56,7 +51,6 @@ export class ViewContextKeyService {
|
|
|
56
51
|
|
|
57
52
|
@postConstruct()
|
|
58
53
|
protected init(): void {
|
|
59
|
-
this._view = this.contextKeyService.createKey('view', '');
|
|
60
54
|
this._viewItem = this.contextKeyService.createKey('viewItem', '');
|
|
61
55
|
this._activeViewlet = this.contextKeyService.createKey('activeViewlet', '');
|
|
62
56
|
this._activePanel = this.contextKeyService.createKey('activePanel', '');
|
|
@@ -69,7 +69,7 @@ export class WindowStateMain implements WindowMain, Disposable {
|
|
|
69
69
|
const uri = URI.revive(uriComponent);
|
|
70
70
|
const url = new CoreURI(encodeURI(uri.toString(true)));
|
|
71
71
|
try {
|
|
72
|
-
await open(this.openerService, url);
|
|
72
|
+
await open(this.openerService, url, { openExternalApp: true });
|
|
73
73
|
return true;
|
|
74
74
|
} catch (e) {
|
|
75
75
|
return false;
|