@theia/plugin-ext 1.53.0-next.6 → 1.53.0-next.64

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.
Files changed (173) hide show
  1. package/lib/common/plugin-api-rpc.d.ts +16 -4
  2. package/lib/common/plugin-api-rpc.d.ts.map +1 -1
  3. package/lib/common/plugin-api-rpc.js +4 -2
  4. package/lib/common/plugin-api-rpc.js.map +1 -1
  5. package/lib/common/rpc-protocol.d.ts +14 -13
  6. package/lib/common/rpc-protocol.d.ts.map +1 -1
  7. package/lib/common/rpc-protocol.js +56 -53
  8. package/lib/common/rpc-protocol.js.map +1 -1
  9. package/lib/hosted/browser/hosted-plugin.d.ts +1 -0
  10. package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
  11. package/lib/hosted/browser/hosted-plugin.js +13 -3
  12. package/lib/hosted/browser/hosted-plugin.js.map +1 -1
  13. package/lib/hosted/node/scanners/scanner-theia.d.ts.map +1 -1
  14. package/lib/hosted/node/scanners/scanner-theia.js +13 -1
  15. package/lib/hosted/node/scanners/scanner-theia.js.map +1 -1
  16. package/lib/main/browser/authentication-main.d.ts +6 -5
  17. package/lib/main/browser/authentication-main.d.ts.map +1 -1
  18. package/lib/main/browser/authentication-main.js +15 -9
  19. package/lib/main/browser/authentication-main.js.map +1 -1
  20. package/lib/main/browser/custom-editors/custom-editor-opener.d.ts +9 -3
  21. package/lib/main/browser/custom-editors/custom-editor-opener.d.ts.map +1 -1
  22. package/lib/main/browser/custom-editors/custom-editor-opener.js +120 -31
  23. package/lib/main/browser/custom-editors/custom-editor-opener.js.map +1 -1
  24. package/lib/main/browser/custom-editors/custom-editor-widget.d.ts +7 -4
  25. package/lib/main/browser/custom-editors/custom-editor-widget.d.ts.map +1 -1
  26. package/lib/main/browser/custom-editors/custom-editor-widget.js +21 -7
  27. package/lib/main/browser/custom-editors/custom-editor-widget.js.map +1 -1
  28. package/lib/main/browser/custom-editors/custom-editors-main.d.ts +3 -4
  29. package/lib/main/browser/custom-editors/custom-editors-main.d.ts.map +1 -1
  30. package/lib/main/browser/custom-editors/custom-editors-main.js +5 -55
  31. package/lib/main/browser/custom-editors/custom-editors-main.js.map +1 -1
  32. package/lib/main/browser/custom-editors/plugin-custom-editor-registry.d.ts +4 -3
  33. package/lib/main/browser/custom-editors/plugin-custom-editor-registry.d.ts.map +1 -1
  34. package/lib/main/browser/custom-editors/plugin-custom-editor-registry.js +24 -16
  35. package/lib/main/browser/custom-editors/plugin-custom-editor-registry.js.map +1 -1
  36. package/lib/main/browser/editors-and-documents-main.d.ts.map +1 -1
  37. package/lib/main/browser/editors-and-documents-main.js +14 -2
  38. package/lib/main/browser/editors-and-documents-main.js.map +1 -1
  39. package/lib/main/browser/main-context.d.ts.map +1 -1
  40. package/lib/main/browser/main-context.js +3 -0
  41. package/lib/main/browser/main-context.js.map +1 -1
  42. package/lib/main/browser/menus/menus-contribution-handler.d.ts.map +1 -1
  43. package/lib/main/browser/menus/menus-contribution-handler.js +1 -1
  44. package/lib/main/browser/menus/menus-contribution-handler.js.map +1 -1
  45. package/lib/main/browser/menus/plugin-menu-command-adapter.d.ts +1 -0
  46. package/lib/main/browser/menus/plugin-menu-command-adapter.d.ts.map +1 -1
  47. package/lib/main/browser/menus/plugin-menu-command-adapter.js +22 -1
  48. package/lib/main/browser/menus/plugin-menu-command-adapter.js.map +1 -1
  49. package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts +2 -2
  50. package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts.map +1 -1
  51. package/lib/main/browser/menus/vscode-theia-menu-mappings.js +2 -0
  52. package/lib/main/browser/menus/vscode-theia-menu-mappings.js.map +1 -1
  53. package/lib/main/browser/notebooks/notebook-documents-and-editors-main.d.ts.map +1 -1
  54. package/lib/main/browser/notebooks/notebook-documents-and-editors-main.js +3 -1
  55. package/lib/main/browser/notebooks/notebook-documents-and-editors-main.js.map +1 -1
  56. package/lib/main/browser/notebooks/notebook-documents-main.d.ts.map +1 -1
  57. package/lib/main/browser/notebooks/notebook-documents-main.js +22 -3
  58. package/lib/main/browser/notebooks/notebook-documents-main.js.map +1 -1
  59. package/lib/main/browser/notebooks/notebook-editors-main.d.ts +1 -1
  60. package/lib/main/browser/notebooks/notebook-editors-main.d.ts.map +1 -1
  61. package/lib/main/browser/notebooks/notebook-editors-main.js +16 -2
  62. package/lib/main/browser/notebooks/notebook-editors-main.js.map +1 -1
  63. package/lib/main/browser/plugin-ext-frontend-module.d.ts.map +1 -1
  64. package/lib/main/browser/plugin-ext-frontend-module.js +18 -0
  65. package/lib/main/browser/plugin-ext-frontend-module.js.map +1 -1
  66. package/lib/main/browser/tabs/tabs-main.d.ts +1 -1
  67. package/lib/main/browser/tabs/tabs-main.d.ts.map +1 -1
  68. package/lib/main/browser/tabs/tabs-main.js +1 -1
  69. package/lib/main/browser/tabs/tabs-main.js.map +1 -1
  70. package/lib/main/browser/text-editor-main.d.ts +6 -3
  71. package/lib/main/browser/text-editor-main.d.ts.map +1 -1
  72. package/lib/main/browser/text-editor-main.js +39 -5
  73. package/lib/main/browser/text-editor-main.js.map +1 -1
  74. package/lib/main/browser/uri-main.d.ts +16 -0
  75. package/lib/main/browser/uri-main.d.ts.map +1 -0
  76. package/lib/main/browser/uri-main.js +64 -0
  77. package/lib/main/browser/uri-main.js.map +1 -0
  78. package/lib/main/browser/webview/webview.d.ts +1 -3
  79. package/lib/main/browser/webview/webview.d.ts.map +1 -1
  80. package/lib/main/browser/webview/webview.js +5 -4
  81. package/lib/main/browser/webview/webview.js.map +1 -1
  82. package/lib/main/browser/webviews-main.d.ts.map +1 -1
  83. package/lib/main/browser/webviews-main.js +6 -1
  84. package/lib/main/browser/webviews-main.js.map +1 -1
  85. package/lib/plugin/authentication-ext.d.ts +3 -2
  86. package/lib/plugin/authentication-ext.d.ts.map +1 -1
  87. package/lib/plugin/authentication-ext.js +8 -5
  88. package/lib/plugin/authentication-ext.js.map +1 -1
  89. package/lib/plugin/custom-editors.d.ts +2 -4
  90. package/lib/plugin/custom-editors.d.ts.map +1 -1
  91. package/lib/plugin/custom-editors.js +5 -7
  92. package/lib/plugin/custom-editors.js.map +1 -1
  93. package/lib/plugin/env.d.ts +2 -0
  94. package/lib/plugin/env.d.ts.map +1 -1
  95. package/lib/plugin/env.js +4 -1
  96. package/lib/plugin/env.js.map +1 -1
  97. package/lib/plugin/known-commands.d.ts.map +1 -1
  98. package/lib/plugin/known-commands.js +1 -0
  99. package/lib/plugin/known-commands.js.map +1 -1
  100. package/lib/plugin/notebook/notebooks.d.ts +1 -0
  101. package/lib/plugin/notebook/notebooks.d.ts.map +1 -1
  102. package/lib/plugin/notebook/notebooks.js +22 -2
  103. package/lib/plugin/notebook/notebooks.js.map +1 -1
  104. package/lib/plugin/plugin-context.d.ts.map +1 -1
  105. package/lib/plugin/plugin-context.js +17 -6
  106. package/lib/plugin/plugin-context.js.map +1 -1
  107. package/lib/plugin/plugin-manager.d.ts.map +1 -1
  108. package/lib/plugin/plugin-manager.js +2 -1
  109. package/lib/plugin/plugin-manager.js.map +1 -1
  110. package/lib/plugin/terminal-ext.d.ts +2 -0
  111. package/lib/plugin/terminal-ext.d.ts.map +1 -1
  112. package/lib/plugin/terminal-ext.js +2 -0
  113. package/lib/plugin/terminal-ext.js.map +1 -1
  114. package/lib/plugin/text-editor.d.ts +1 -1
  115. package/lib/plugin/text-editor.d.ts.map +1 -1
  116. package/lib/plugin/text-editor.js.map +1 -1
  117. package/lib/plugin/type-converters.d.ts +5 -0
  118. package/lib/plugin/type-converters.d.ts.map +1 -1
  119. package/lib/plugin/type-converters.js +24 -3
  120. package/lib/plugin/type-converters.js.map +1 -1
  121. package/lib/plugin/types-impl.d.ts +5 -0
  122. package/lib/plugin/types-impl.d.ts.map +1 -1
  123. package/lib/plugin/types-impl.js +9 -1
  124. package/lib/plugin/types-impl.js.map +1 -1
  125. package/lib/plugin/uri-ext.d.ts +37 -0
  126. package/lib/plugin/uri-ext.d.ts.map +1 -0
  127. package/lib/plugin/uri-ext.js +50 -0
  128. package/lib/plugin/uri-ext.js.map +1 -0
  129. package/lib/plugin/webviews.js +1 -1
  130. package/lib/plugin/webviews.js.map +1 -1
  131. package/package.json +29 -29
  132. package/src/common/plugin-api-rpc.ts +21 -6
  133. package/src/common/rpc-protocol.ts +62 -66
  134. package/src/hosted/browser/hosted-plugin.ts +16 -5
  135. package/src/hosted/node/scanners/scanner-theia.ts +12 -1
  136. package/src/main/browser/authentication-main.ts +24 -11
  137. package/src/main/browser/custom-editors/custom-editor-opener.tsx +125 -25
  138. package/src/main/browser/custom-editors/custom-editor-widget.ts +20 -11
  139. package/src/main/browser/custom-editors/custom-editors-main.ts +11 -70
  140. package/src/main/browser/custom-editors/plugin-custom-editor-registry.ts +20 -14
  141. package/src/main/browser/editors-and-documents-main.ts +25 -2
  142. package/src/main/browser/main-context.ts +4 -0
  143. package/src/main/browser/menus/menus-contribution-handler.ts +2 -1
  144. package/src/main/browser/menus/plugin-menu-command-adapter.ts +22 -1
  145. package/src/main/browser/menus/vscode-theia-menu-mappings.ts +3 -1
  146. package/src/main/browser/notebooks/notebook-documents-and-editors-main.ts +5 -2
  147. package/src/main/browser/notebooks/notebook-documents-main.ts +24 -4
  148. package/src/main/browser/notebooks/notebook-editors-main.ts +15 -2
  149. package/src/main/browser/plugin-ext-frontend-module.ts +23 -4
  150. package/src/main/browser/tabs/tabs-main.ts +6 -2
  151. package/src/main/browser/text-editor-main.ts +55 -14
  152. package/src/main/browser/uri-main.ts +72 -0
  153. package/src/main/browser/webview/pre/service-worker.js +2 -1
  154. package/src/main/browser/webview/webview.ts +5 -6
  155. package/src/main/browser/webviews-main.ts +6 -1
  156. package/src/plugin/authentication-ext.ts +9 -5
  157. package/src/plugin/custom-editors.ts +8 -10
  158. package/src/plugin/env.ts +6 -1
  159. package/src/plugin/known-commands.ts +1 -0
  160. package/src/plugin/notebook/notebooks.ts +21 -0
  161. package/src/plugin/plugin-context.ts +19 -8
  162. package/src/plugin/plugin-manager.ts +2 -1
  163. package/src/plugin/terminal-ext.ts +3 -0
  164. package/src/plugin/text-editor.ts +1 -1
  165. package/src/plugin/type-converters.ts +20 -0
  166. package/src/plugin/types-impl.ts +10 -0
  167. package/src/plugin/uri-ext.ts +60 -0
  168. package/src/plugin/webviews.ts +1 -1
  169. package/lib/common/proxy-handler.d.ts +0 -73
  170. package/lib/common/proxy-handler.d.ts.map +0 -1
  171. package/lib/common/proxy-handler.js +0 -106
  172. package/lib/common/proxy-handler.js.map +0 -1
  173. package/src/common/proxy-handler.ts +0 -143
@@ -21,7 +21,7 @@
21
21
  import { Disposable, DisposableCollection } from '@theia/core';
22
22
  import { interfaces } from '@theia/core/shared/inversify';
23
23
  import { UriComponents } from '@theia/core/lib/common/uri';
24
- import { NotebookEditorWidget, NotebookService, NotebookEditorWidgetService } from '@theia/notebook/lib/browser';
24
+ import { NotebookEditorWidget, NotebookService, NotebookEditorWidgetService, NotebookCellEditorService } from '@theia/notebook/lib/browser';
25
25
  import { NotebookModel } from '@theia/notebook/lib/browser/view-model/notebook-model';
26
26
  import { MAIN_RPC_CONTEXT, NotebookDocumentsAndEditorsDelta, NotebookDocumentsAndEditorsMain, NotebookEditorAddData, NotebookModelAddedData, NotebooksExt } from '../../../common';
27
27
  import { RPCProtocol } from '../../../common/rpc-protocol';
@@ -105,6 +105,9 @@ export class NotebooksAndEditorsMain implements NotebookDocumentsAndEditorsMain
105
105
  this.notebookService = container.get(NotebookService);
106
106
  this.notebookEditorService = container.get(NotebookEditorWidgetService);
107
107
  this.WidgetManager = container.get(WidgetManager);
108
+ const notebookCellEditorService = container.get(NotebookCellEditorService);
109
+
110
+ notebookCellEditorService.onDidChangeFocusedCellEditor(editor => this.proxy.$acceptActiveCellEditorChange(editor?.uri.toString() ?? null), this, this.disposables);
108
111
 
109
112
  this.notebookService.onDidAddNotebookDocument(async () => this.updateState(), this, this.disposables);
110
113
  this.notebookService.onDidRemoveNotebookDocument(async () => this.updateState(), this, this.disposables);
@@ -242,7 +245,7 @@ export class NotebooksAndEditorsMain implements NotebookDocumentsAndEditorsMain
242
245
  return {
243
246
  id: notebookEditor.id,
244
247
  documentUri: uri.toComponents(),
245
- selections: [],
248
+ selections: [{ start: 0, end: 0 }],
246
249
  visibleRanges: []
247
250
  };
248
251
  }
@@ -21,7 +21,7 @@ import { NotebookModelResolverService } from '@theia/notebook/lib/browser';
21
21
  import { NotebookModel } from '@theia/notebook/lib/browser/view-model/notebook-model';
22
22
  import { NotebookCellsChangeType } from '@theia/notebook/lib/common';
23
23
  import { NotebookMonacoTextModelService } from '@theia/notebook/lib/browser/service/notebook-monaco-text-model-service';
24
- import { MAIN_RPC_CONTEXT, NotebookCellsChangedEventDto, NotebookDataDto, NotebookDocumentsExt, NotebookDocumentsMain } from '../../../common';
24
+ import { MAIN_RPC_CONTEXT, NotebookCellsChangedEventDto, NotebookDataDto, NotebookDocumentsExt, NotebookDocumentsMain, NotebookRawContentEventDto } from '../../../common';
25
25
  import { RPCProtocol } from '../../../common/rpc-protocol';
26
26
  import { NotebookDto } from './notebook-dto';
27
27
  import { MonacoEditorModel } from '@theia/monaco/lib/browser/monaco-editor-model';
@@ -156,19 +156,39 @@ export class NotebookDocumentsMainImpl implements NotebookDocumentsMain {
156
156
  // ref.dispose();
157
157
  // });
158
158
 
159
+ const uriComponents = ref.uri.toComponents();
159
160
  // untitled notebooks are dirty by default
160
- this.proxy.$acceptDirtyStateChanged(ref.uri.toComponents(), true);
161
+ this.proxy.$acceptDirtyStateChanged(uriComponents, true);
161
162
 
162
- // apply content changes... slightly HACKY -> this triggers a change event
163
+ // apply content changes...
163
164
  if (options.content) {
164
165
  const data = NotebookDto.fromNotebookDataDto(options.content);
165
166
  ref.setData(data);
167
+
168
+ // Create and send a change events
169
+ const rawEvents: NotebookRawContentEventDto[] = [];
170
+ if (options.content.cells && options.content.cells.length > 0) {
171
+ rawEvents.push({
172
+ kind: NotebookCellsChangeType.ModelChange,
173
+ changes: [{ start: 0, deleteCount: 0, newItems: ref.cells.map(NotebookDto.toNotebookCellDto) }]
174
+ });
175
+ }
176
+ if (options.content.metadata) {
177
+ rawEvents.push({
178
+ kind: NotebookCellsChangeType.ChangeDocumentMetadata,
179
+ metadata: options.content.metadata
180
+ });
181
+ }
182
+ if (rawEvents.length > 0) {
183
+ this.proxy.$acceptModelChanged(uriComponents, { versionId: 1, rawEvents }, true);
184
+ }
166
185
  }
167
- return ref.uri.toComponents();
186
+ return uriComponents;
168
187
  }
169
188
 
170
189
  async $tryOpenNotebook(uriComponents: UriComponents): Promise<UriComponents> {
171
190
  const uri = URI.fromComponents(uriComponents);
191
+ await this.notebookModelResolverService.resolve(uri);
172
192
  return uri.toComponents();
173
193
  }
174
194
 
@@ -54,12 +54,25 @@ export class NotebookEditorsMainImpl implements NotebookEditorsMain {
54
54
  throw new Error('Method not implemented.');
55
55
  }
56
56
  $trySetSelections(id: string, range: CellRange[]): void {
57
- throw new Error('Method not implemented.');
57
+ if (!this.mainThreadEditors.has(id)) {
58
+ throw new Error('Editor not found');
59
+ }
60
+ const editor = this.mainThreadEditors.get(id);
61
+ editor?.model?.setSelectedCell(editor.model.cells[range[0].start]);
58
62
  }
59
63
 
60
- handleEditorsAdded(editors: readonly NotebookEditorWidget[]): void {
64
+ async handleEditorsAdded(editors: readonly NotebookEditorWidget[]): Promise<void> {
61
65
  for (const editor of editors) {
62
66
  this.mainThreadEditors.set(editor.id, editor);
67
+ const model = await editor.ready;
68
+ model.onDidChangeSelectedCell(e => {
69
+ const newCellIndex = e.cell ? model.cells.indexOf(e.cell) : -1;
70
+ this.proxy.$acceptEditorPropertiesChanged(editor.id, {
71
+ selections: {
72
+ selections: newCellIndex >= 0 ? [{ start: newCellIndex, end: newCellIndex }] : []
73
+ }
74
+ });
75
+ });
63
76
  }
64
77
  }
65
78
 
@@ -21,10 +21,10 @@ import '../../../src/main/browser/style/comments.css';
21
21
  import { ContainerModule } from '@theia/core/shared/inversify';
22
22
  import {
23
23
  FrontendApplicationContribution, WidgetFactory, bindViewContribution,
24
- ViewContainerIdentifier, ViewContainer, createTreeContainer, TreeWidget, LabelProviderContribution,
25
- UndoRedoHandler
24
+ ViewContainerIdentifier, ViewContainer, createTreeContainer, TreeWidget, LabelProviderContribution, LabelProvider,
25
+ UndoRedoHandler, DiffUris, Navigatable, SplitWidget
26
26
  } from '@theia/core/lib/browser';
27
- import { MaybePromise, CommandContribution, ResourceResolver, bindContributionProvider } from '@theia/core/lib/common';
27
+ import { MaybePromise, CommandContribution, ResourceResolver, bindContributionProvider, URI, generateUuid } from '@theia/core/lib/common';
28
28
  import { WebSocketConnectionProvider } from '@theia/core/lib/browser/messaging';
29
29
  import { HostedPluginSupport } from '../../hosted/browser/hosted-plugin';
30
30
  import { HostedPluginWatcher } from '../../hosted/browser/hosted-plugin-watcher';
@@ -200,6 +200,25 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
200
200
  bind(CustomEditorUndoRedoHandler).toSelf().inSingletonScope();
201
201
  bind(UndoRedoHandler).toService(CustomEditorUndoRedoHandler);
202
202
 
203
+ bind(WidgetFactory).toDynamicValue(ctx => ({
204
+ id: CustomEditorWidget.SIDE_BY_SIDE_FACTORY_ID,
205
+ createWidget: (arg: { uri: string, viewType: string }) => {
206
+ const uri = new URI(arg.uri);
207
+ const [leftUri, rightUri] = DiffUris.decode(uri);
208
+ const navigatable: Navigatable = {
209
+ getResourceUri: () => rightUri,
210
+ createMoveToUri: resourceUri => DiffUris.encode(leftUri, rightUri.withPath(resourceUri.path))
211
+ };
212
+ const widget = new SplitWidget({ navigatable });
213
+ widget.id = arg.viewType + '.side-by-side:' + generateUuid();
214
+ const labelProvider = ctx.container.get(LabelProvider);
215
+ widget.title.label = labelProvider.getName(uri);
216
+ widget.title.iconClass = labelProvider.getIcon(uri);
217
+ widget.title.closable = true;
218
+ return widget;
219
+ }
220
+ })).inSingletonScope();
221
+
203
222
  bind(PluginViewWidget).toSelf();
204
223
  bind(WidgetFactory).toDynamicValue(({ container }) => ({
205
224
  id: PLUGIN_VIEW_FACTORY_ID,
@@ -267,6 +286,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
267
286
  bind(CellOutputWebviewFactory).toFactory(ctx => async (cell: NotebookCellModel, notebook: NotebookModel) =>
268
287
  createCellOutputWebviewContainer(ctx.container, cell, notebook).getAsync(CellOutputWebviewImpl)
269
288
  );
270
-
271
289
  bindContributionProvider(bind, ArgumentProcessorContribution);
290
+
272
291
  });
@@ -231,9 +231,13 @@ export class TabsMainImpl implements TabsMain, Disposable {
231
231
  return { kind: TabInputKind.UnknownInput };
232
232
  }
233
233
 
234
- protected connectToSignal<T>(disposableList: DisposableCollection, signal: { connect(listener: T, context: unknown): void, disconnect(listener: T): void }, listener: T): void {
234
+ protected connectToSignal<T>(disposableList: DisposableCollection,
235
+ signal: {
236
+ connect(listener: T, context: unknown): void,
237
+ disconnect(listener: T, context: unknown): void
238
+ }, listener: T): void {
235
239
  signal.connect(listener, this);
236
- disposableList.push(Disposable.create(() => signal.disconnect(listener)));
240
+ disposableList.push(Disposable.create(() => signal.disconnect(listener, this)));
237
241
  }
238
242
 
239
243
  protected tabDtosEqual(a: TabDto, b: TabDto): boolean {
@@ -33,11 +33,14 @@ import { Range } from '../../common/plugin-api-rpc-model';
33
33
  import { Emitter, Event } from '@theia/core';
34
34
  import { TextEditorCursorStyle, cursorStyleToString } from '../../common/editor-options';
35
35
  import { TextEditorLineNumbersStyle, EndOfLine } from '../../plugin/types-impl';
36
+ import { SimpleMonacoEditor } from '@theia/monaco/lib/browser/simple-monaco-editor';
37
+ import { EndOfLineSequence, ITextModel } from '@theia/monaco-editor-core/esm/vs/editor/common/model';
38
+ import { EditorOption, RenderLineNumbersType } from '@theia/monaco-editor-core/esm/vs/editor/common/config/editorOptions';
36
39
 
37
40
  export class TextEditorMain implements Disposable {
38
41
 
39
42
  private properties: TextEditorPropertiesMain | undefined;
40
- private editor: MonacoEditor | undefined;
43
+ private editor: MonacoEditor | SimpleMonacoEditor | undefined;
41
44
 
42
45
  private readonly onPropertiesChangedEmitter = new Emitter<EditorChangedPropertiesData>();
43
46
 
@@ -48,8 +51,8 @@ export class TextEditorMain implements Disposable {
48
51
 
49
52
  constructor(
50
53
  private id: string,
51
- private model: monaco.editor.IModel,
52
- editor: MonacoEditor
54
+ private model: monaco.editor.IModel | ITextModel,
55
+ editor: MonacoEditor | SimpleMonacoEditor
53
56
  ) {
54
57
  this.toDispose.push(this.model.onDidChangeOptions(() =>
55
58
  this.updateProperties(undefined)
@@ -76,7 +79,7 @@ export class TextEditorMain implements Disposable {
76
79
 
77
80
  protected readonly toDisposeOnEditor = new DisposableCollection();
78
81
 
79
- private setEditor(editor?: MonacoEditor): void {
82
+ private setEditor(editor?: MonacoEditor | SimpleMonacoEditor): void {
80
83
  if (this.editor === editor) {
81
84
  return;
82
85
  }
@@ -115,7 +118,7 @@ export class TextEditorMain implements Disposable {
115
118
  return this.id;
116
119
  }
117
120
 
118
- getModel(): monaco.editor.IModel {
121
+ getModel(): monaco.editor.IModel | ITextModel {
119
122
  return this.model;
120
123
  }
121
124
 
@@ -208,7 +211,7 @@ export class TextEditorMain implements Disposable {
208
211
  }
209
212
 
210
213
  revealRange(range: monaco.Range, revealType: TextEditorRevealType): void {
211
- if (!this.editor) {
214
+ if (!this.editor || this.editor instanceof SimpleMonacoEditor) {
212
215
  return;
213
216
  }
214
217
  switch (revealType) {
@@ -240,10 +243,14 @@ export class TextEditorMain implements Disposable {
240
243
  return false;
241
244
  }
242
245
 
243
- if (opts.setEndOfLine === EndOfLine.CRLF) {
246
+ if (opts.setEndOfLine === EndOfLine.CRLF && !this.isSimpleWidget(this.model)) {
244
247
  this.model.setEOL(monaco.editor.EndOfLineSequence.CRLF);
245
- } else if (opts.setEndOfLine === EndOfLine.LF) {
248
+ } else if (opts.setEndOfLine === EndOfLine.LF && !this.isSimpleWidget(this.model)) {
246
249
  this.model.setEOL(monaco.editor.EndOfLineSequence.LF);
250
+ } else if (opts.setEndOfLine === EndOfLine.CRLF && this.isSimpleWidget(this.model)) {
251
+ this.model.setEOL(EndOfLineSequence.CRLF);
252
+ } else if (opts.setEndOfLine === EndOfLine.LF && this.isSimpleWidget(this.model)) {
253
+ this.model.setEOL(EndOfLineSequence.CRLF);
247
254
  }
248
255
 
249
256
  const editOperations: monaco.editor.IIdentifiedSingleEditOperation[] = [];
@@ -311,6 +318,10 @@ export class TextEditorMain implements Disposable {
311
318
  private static toMonacoSelections(selection: Selection): monaco.Selection {
312
319
  return new monaco.Selection(selection.selectionStartLineNumber, selection.selectionStartColumn, selection.positionLineNumber, selection.positionColumn);
313
320
  }
321
+
322
+ private isSimpleWidget(model: monaco.editor.IModel | ITextModel): model is ITextModel {
323
+ return !!(model as ITextModel).isForSimpleWidget;
324
+ }
314
325
  }
315
326
 
316
327
  // TODO move to monaco typings!
@@ -362,17 +373,26 @@ export class TextEditorPropertiesMain {
362
373
  return undefined;
363
374
  }
364
375
 
365
- static readFromEditor(prevProperties: TextEditorPropertiesMain | undefined, model: monaco.editor.IModel, editor: MonacoEditor): TextEditorPropertiesMain {
376
+ static readFromEditor(prevProperties: TextEditorPropertiesMain | undefined,
377
+ model: monaco.editor.IModel | ITextModel,
378
+ editor: MonacoEditor | SimpleMonacoEditor): TextEditorPropertiesMain {
379
+
366
380
  const selections = TextEditorPropertiesMain.getSelectionsFromEditor(prevProperties, editor);
367
381
  const options = TextEditorPropertiesMain.getOptionsFromEditor(prevProperties, model, editor);
368
382
  const visibleRanges = TextEditorPropertiesMain.getVisibleRangesFromEditor(prevProperties, editor);
369
383
  return new TextEditorPropertiesMain(selections, options, visibleRanges);
370
384
  }
371
385
 
372
- private static getSelectionsFromEditor(prevProperties: TextEditorPropertiesMain | undefined, editor: MonacoEditor): monaco.Selection[] {
386
+ private static getSelectionsFromEditor(prevProperties: TextEditorPropertiesMain | undefined, editor: MonacoEditor | SimpleMonacoEditor): monaco.Selection[] {
373
387
  let result: monaco.Selection[] | undefined = undefined;
374
- if (editor) {
388
+ if (editor && editor instanceof MonacoEditor) {
375
389
  result = editor.getControl().getSelections() || undefined;
390
+ } else if (editor && editor instanceof SimpleMonacoEditor) {
391
+ result = editor.getControl().getSelections()?.map(selection => new monaco.Selection(
392
+ selection.startLineNumber,
393
+ selection.startColumn,
394
+ selection.positionLineNumber,
395
+ selection.positionColumn));
376
396
  }
377
397
 
378
398
  if (!result && prevProperties) {
@@ -385,14 +405,16 @@ export class TextEditorPropertiesMain {
385
405
  return result;
386
406
  }
387
407
 
388
- private static getOptionsFromEditor(prevProperties: TextEditorPropertiesMain | undefined, model: monaco.editor.IModel, editor: MonacoEditor): TextEditorConfiguration {
408
+ private static getOptionsFromEditor(prevProperties: TextEditorPropertiesMain | undefined,
409
+ model: monaco.editor.IModel | ITextModel,
410
+ editor: MonacoEditor | SimpleMonacoEditor): TextEditorConfiguration {
389
411
  if (model.isDisposed()) {
390
412
  return prevProperties!.options;
391
413
  }
392
414
 
393
415
  let cursorStyle: TextEditorCursorStyle;
394
416
  let lineNumbers: TextEditorLineNumbersStyle;
395
- if (editor) {
417
+ if (editor && editor instanceof MonacoEditor) {
396
418
  const editorOptions = editor.getControl().getOptions();
397
419
  const lineNumbersOpts = editorOptions.get(monaco.editor.EditorOption.lineNumbers);
398
420
  cursorStyle = editorOptions.get(monaco.editor.EditorOption.cursorStyle);
@@ -410,6 +432,25 @@ export class TextEditorPropertiesMain {
410
432
  lineNumbers = TextEditorLineNumbersStyle.On;
411
433
  break;
412
434
  }
435
+ } else if (editor && editor instanceof SimpleMonacoEditor) {
436
+ const editorOptions = editor.getControl().getOptions();
437
+ const lineNumbersOpts = editorOptions.get(EditorOption.lineNumbers);
438
+ cursorStyle = editorOptions.get(EditorOption.cursorStyle);
439
+ switch (lineNumbersOpts.renderType) {
440
+ case RenderLineNumbersType.Off:
441
+ lineNumbers = TextEditorLineNumbersStyle.Off;
442
+ break;
443
+ case RenderLineNumbersType.Relative:
444
+ lineNumbers = TextEditorLineNumbersStyle.Relative;
445
+ break;
446
+ case RenderLineNumbersType.Interval:
447
+ lineNumbers = TextEditorLineNumbersStyle.Interval;
448
+ break;
449
+ default:
450
+ lineNumbers = TextEditorLineNumbersStyle.On;
451
+ break;
452
+ }
453
+
413
454
  } else if (prevProperties) {
414
455
  cursorStyle = prevProperties.options.cursorStyle;
415
456
  lineNumbers = prevProperties.options.lineNumbers;
@@ -428,7 +469,7 @@ export class TextEditorPropertiesMain {
428
469
  };
429
470
  }
430
471
 
431
- private static getVisibleRangesFromEditor(prevProperties: TextEditorPropertiesMain | undefined, editor: MonacoEditor): monaco.Range[] {
472
+ private static getVisibleRangesFromEditor(prevProperties: TextEditorPropertiesMain | undefined, editor: MonacoEditor | SimpleMonacoEditor): monaco.Range[] {
432
473
  if (editor) {
433
474
  return editor.getControl().getVisibleRanges();
434
475
  }
@@ -0,0 +1,72 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2024 STMicroelectronics.
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 { Disposable, URI } from '@theia/core';
18
+ import { MAIN_RPC_CONTEXT, UriExt, UriMain } from '../../common';
19
+ import { RPCProtocol } from '../../common/rpc-protocol';
20
+ import { interfaces } from '@theia/core/shared/inversify';
21
+ import { OpenHandler, OpenerOptions, OpenerService } from '@theia/core/lib/browser';
22
+ import { FrontendApplicationConfigProvider } from '@theia/core/lib/browser/frontend-application-config-provider';
23
+ import { HostedPluginSupport } from '../../hosted/browser/hosted-plugin';
24
+
25
+ export class UriMainImpl implements UriMain, Disposable {
26
+ private readonly proxy: UriExt;
27
+ private handlers = new Set<string>();
28
+ private readonly openerService: OpenerService;
29
+ private readonly pluginSupport: HostedPluginSupport;
30
+ private readonly openHandler: OpenHandler;
31
+
32
+ constructor(rpc: RPCProtocol, container: interfaces.Container) {
33
+ this.proxy = rpc.getProxy(MAIN_RPC_CONTEXT.URI_EXT);
34
+ this.openerService = container.get(OpenerService);
35
+ this.pluginSupport = container.get(HostedPluginSupport);
36
+
37
+ this.openHandler = {
38
+ id: 'theia-plugin-open-handler',
39
+ canHandle: async (uri: URI, options?: OpenerOptions | undefined): Promise<number> => {
40
+ if (uri.scheme !== FrontendApplicationConfigProvider.get().electron.uriScheme) {
41
+ return 0;
42
+ }
43
+ await this.pluginSupport.activateByUri(uri.scheme, uri.authority);
44
+ if (this.handlers.has(uri.authority)) {
45
+ return 500;
46
+ }
47
+ return 0;
48
+ },
49
+ open: async (uri: URI, options?: OpenerOptions | undefined): Promise<undefined> => {
50
+ if (!this.handlers.has(uri.authority)) {
51
+ throw new Error(`No plugin to handle this uri: : '${uri}'`);
52
+ }
53
+ this.proxy.$handleExternalUri(uri.toComponents());
54
+ }
55
+ };
56
+
57
+ this.openerService.addHandler?.(this.openHandler);
58
+ }
59
+
60
+ dispose(): void {
61
+ this.openerService.removeHandler?.(this.openHandler);
62
+ this.handlers.clear();
63
+ }
64
+
65
+ async $registerUriHandler(pluginId: string, extensionDisplayName: string): Promise<void> {
66
+ this.handlers.add(pluginId);
67
+ }
68
+
69
+ async $unregisterUriHandler(pluginId: string): Promise<void> {
70
+ this.handlers.delete(pluginId);
71
+ }
72
+ }
@@ -226,7 +226,8 @@ async function processResourceRequest(event, requestUrl, resourceRoot) {
226
226
 
227
227
  parentClient.postMessage({
228
228
  channel: 'load-resource',
229
- path: resourcePath
229
+ path: resourcePath,
230
+ query: requestUrl.search.replace(/^\?/, '')
230
231
  });
231
232
 
232
233
  return resourceRequestStore.create(webviewId, resourcePath)
@@ -48,7 +48,6 @@ import { isFirefox } from '@theia/core/lib/browser/browser';
48
48
  import { FileService } from '@theia/filesystem/lib/browser/file-service';
49
49
  import { FileOperationError, FileOperationResult } from '@theia/filesystem/lib/common/files';
50
50
  import { BinaryBufferReadableStream } from '@theia/core/lib/common/buffer';
51
- import { ViewColumn } from '../../../plugin/types-impl';
52
51
  import { ExtractableWidget } from '@theia/core/lib/browser/widgets/extractable-widget';
53
52
  import { BadgeWidget } from '@theia/core/lib/browser/view-container';
54
53
  import { MenuPath } from '@theia/core';
@@ -185,7 +184,6 @@ export class WebviewWidget extends BaseWidget implements StatefulWidget, Extract
185
184
  }
186
185
 
187
186
  viewType: string;
188
- viewColumn: ViewColumn;
189
187
  options: WebviewPanelOptions = {};
190
188
 
191
189
  protected ready = new Deferred<void>();
@@ -352,7 +350,7 @@ export class WebviewWidget extends BaseWidget implements StatefulWidget, Extract
352
350
  /* no-op: webview loses focus only if another element gains focus in the main window */
353
351
  }));
354
352
  this.toHide.push(this.on(WebviewMessageChannels.doReload, () => this.reload()));
355
- this.toHide.push(this.on(WebviewMessageChannels.loadResource, (entry: any) => this.loadResource(entry.path)));
353
+ this.toHide.push(this.on(WebviewMessageChannels.loadResource, (entry: any) => this.loadResource(entry.path, entry.query)));
356
354
  this.toHide.push(this.on(WebviewMessageChannels.loadLocalhost, (entry: any) =>
357
355
  this.loadLocalhost(entry.origin)
358
356
  ));
@@ -544,10 +542,11 @@ export class WebviewWidget extends BaseWidget implements StatefulWidget, Extract
544
542
  return undefined;
545
543
  }
546
544
 
547
- protected async loadResource(requestPath: string): Promise<void> {
548
- const normalizedUri = this.normalizeRequestUri(requestPath);
545
+ protected async loadResource(requestPath: string, requestQuery: string = ''): Promise<void> {
546
+ const normalizedUri = this.normalizeRequestUri(requestPath).withQuery(decodeURIComponent(requestQuery));
549
547
  // browser cache does not support file scheme, normalize to current endpoint scheme and host
550
- const cacheUrl = new Endpoint({ path: normalizedUri.path.toString() }).getRestUrl().toString();
548
+ // use requestPath rather than normalizedUri.path to preserve the scheme of the requested resource as a path segment
549
+ const cacheUrl = new Endpoint({ path: requestPath }).getRestUrl().withQuery(decodeURIComponent(requestQuery)).toString();
551
550
 
552
551
  try {
553
552
  if (this.contentOptions.localResourceRoots) {
@@ -191,7 +191,12 @@ export class WebviewsMainImpl implements WebviewsMain, Disposable {
191
191
 
192
192
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
193
193
  async $postMessage(handle: string, value: any): Promise<boolean> {
194
- const webview = await this.getWebview(handle);
194
+ // Due to async nature of $postMessage, the webview may have been disposed in the meantime.
195
+ // Therefore, don't throw an error if the webview is not found, but return false in this case.
196
+ const webview = await this.tryGetWebview(handle);
197
+ if (!webview) {
198
+ return false;
199
+ }
195
200
  webview.sendMessage(value);
196
201
  return true;
197
202
  }
@@ -57,6 +57,10 @@ export class AuthenticationExtImpl implements AuthenticationExt {
57
57
  return this.proxy.$getSession(providerId, scopes, extensionId, extensionName, options);
58
58
  }
59
59
 
60
+ getAccounts(providerId: string): Thenable<readonly theia.AuthenticationSessionAccountInformation[]> {
61
+ return this.proxy.$getAccounts(providerId);
62
+ }
63
+
60
64
  registerAuthenticationProvider(id: string, label: string, provider: theia.AuthenticationProvider, options?: theia.AuthenticationProviderOptions): theia.Disposable {
61
65
  if (this.authenticationProviders.get(id)) {
62
66
  throw new Error(`An authentication provider with id '${id}' is already registered.`);
@@ -64,7 +68,7 @@ export class AuthenticationExtImpl implements AuthenticationExt {
64
68
 
65
69
  this.authenticationProviders.set(id, provider);
66
70
 
67
- provider.getSessions().then(sessions => { // sessions might have been restored from secret storage
71
+ provider.getSessions(undefined, {}).then(sessions => { // sessions might have been restored from secret storage
68
72
  if (sessions.length > 0) {
69
73
  this.proxy.$onDidChangeSessions(id, {
70
74
  added: sessions,
@@ -87,10 +91,10 @@ export class AuthenticationExtImpl implements AuthenticationExt {
87
91
  });
88
92
  }
89
93
 
90
- $createSession(providerId: string, scopes: string[]): Promise<theia.AuthenticationSession> {
94
+ $createSession(providerId: string, scopes: string[], options: theia.AuthenticationProviderSessionOptions): Promise<theia.AuthenticationSession> {
91
95
  const authProvider = this.authenticationProviders.get(providerId);
92
96
  if (authProvider) {
93
- return Promise.resolve(authProvider.createSession(scopes));
97
+ return Promise.resolve(authProvider.createSession(scopes, options));
94
98
  }
95
99
 
96
100
  throw new Error(`Unable to find authentication provider with handle: ${providerId}`);
@@ -105,10 +109,10 @@ export class AuthenticationExtImpl implements AuthenticationExt {
105
109
  throw new Error(`Unable to find authentication provider with handle: ${providerId}`);
106
110
  }
107
111
 
108
- async $getSessions(providerId: string, scopes?: string[]): Promise<ReadonlyArray<theia.AuthenticationSession>> {
112
+ async $getSessions(providerId: string, scopes: string[] | undefined, options: theia.AuthenticationProviderSessionOptions): Promise<ReadonlyArray<theia.AuthenticationSession>> {
109
113
  const authProvider = this.authenticationProviders.get(providerId);
110
114
  if (authProvider) {
111
- const sessions = await authProvider.getSessions(scopes);
115
+ const sessions = await authProvider.getSessions(scopes, options);
112
116
 
113
117
  /* Wrap the session object received from the plugin to prevent serialization mismatches
114
118
  e.g. if the plugin object is constructed with the help of getters they won't be serialized:
@@ -25,11 +25,11 @@ import { RPCProtocol } from '../common/rpc-protocol';
25
25
  import { Disposable, URI } from './types-impl';
26
26
  import { UriComponents } from '../common/uri-components';
27
27
  import { DocumentsExtImpl } from './documents';
28
- import { WebviewImpl, WebviewsExtImpl } from './webviews';
28
+ import { WebviewsExtImpl } from './webviews';
29
29
  import { CancellationToken, CancellationTokenSource } from '@theia/core/lib/common/cancellation';
30
30
  import { DisposableCollection } from '@theia/core/lib/common/disposable';
31
- import { WorkspaceExtImpl } from './workspace';
32
31
  import { Cache } from '../common/cache';
32
+ import * as Converters from './type-converters';
33
33
 
34
34
  export class CustomEditorsExtImpl implements CustomEditorsExt {
35
35
  private readonly proxy: CustomEditorsMain;
@@ -38,8 +38,7 @@ export class CustomEditorsExtImpl implements CustomEditorsExt {
38
38
 
39
39
  constructor(rpc: RPCProtocol,
40
40
  private readonly documentExt: DocumentsExtImpl,
41
- private readonly webviewExt: WebviewsExtImpl,
42
- private readonly workspace: WorkspaceExtImpl) {
41
+ private readonly webviewExt: WebviewsExtImpl) {
43
42
  this.proxy = rpc.getProxy(PLUGIN_RPC_CONTEXT.CUSTOM_EDITORS_MAIN);
44
43
  }
45
44
 
@@ -116,22 +115,21 @@ export class CustomEditorsExtImpl implements CustomEditorsExt {
116
115
  document.dispose();
117
116
  }
118
117
 
119
- async $resolveWebviewEditor<T>(
118
+ async $resolveWebviewEditor(
120
119
  resource: UriComponents,
121
120
  handler: string,
122
121
  viewType: string,
123
122
  title: string,
124
- widgetOpenerOptions: object | undefined,
125
- options: theia.WebviewPanelOptions & theia.WebviewOptions,
123
+ position: number,
124
+ options: theia.WebviewPanelOptions,
126
125
  cancellation: CancellationToken
127
126
  ): Promise<void> {
128
127
  const entry = this.editorProviders.get(viewType);
129
128
  if (!entry) {
130
129
  throw new Error(`No provider found for '${viewType}'`);
131
130
  }
132
- const panel = this.webviewExt.createWebviewPanel(viewType, title, {}, options, entry.plugin, handler, false);
133
- const webviewOptions = WebviewImpl.toWebviewOptions(options, this.workspace, entry.plugin);
134
- await this.proxy.$createCustomEditorPanel(handler, title, widgetOpenerOptions, webviewOptions);
131
+ const viewColumn = Converters.toViewColumn(position);
132
+ const panel = this.webviewExt.createWebviewPanel(viewType, title, { viewColumn }, options, entry.plugin, handler, false);
135
133
 
136
134
  const revivedResource = URI.revive(resource);
137
135
 
package/src/plugin/env.ts CHANGED
@@ -35,6 +35,7 @@ export abstract class EnvExtImpl {
35
35
  private envSessionId: string;
36
36
  private host: string;
37
37
  private applicationRoot: string;
38
+ private appUriScheme: string;
38
39
  private _remoteName: string | undefined;
39
40
 
40
41
  constructor() {
@@ -89,6 +90,10 @@ export abstract class EnvExtImpl {
89
90
  this.applicationRoot = appRoot;
90
91
  }
91
92
 
93
+ setAppUriScheme(uriScheme: string): void {
94
+ this.appUriScheme = uriScheme;
95
+ }
96
+
92
97
  getClientOperatingSystem(): Promise<theia.OperatingSystem> {
93
98
  return this.proxy.$getClientOperatingSystem();
94
99
  }
@@ -121,7 +126,7 @@ export abstract class EnvExtImpl {
121
126
  return this.envSessionId;
122
127
  }
123
128
  get uriScheme(): string {
124
- return 'theia';
129
+ return this.appUriScheme;
125
130
  }
126
131
  get uiKind(): theia.UIKind {
127
132
  return this.ui;
@@ -297,6 +297,7 @@ export namespace KnownCommands {
297
297
  mappings['vscode.executeFormatDocumentProvider'] = ['vscode.executeFormatDocumentProvider', CONVERT_VSCODE_TO_MONACO, CONVERT_MONACO_TO_VSCODE];
298
298
  mappings['vscode.executeFormatRangeProvider'] = ['vscode.executeFormatRangeProvider', CONVERT_VSCODE_TO_MONACO, CONVERT_MONACO_TO_VSCODE];
299
299
  mappings['vscode.executeFormatOnTypeProvider'] = ['vscode.executeFormatOnTypeProvider', CONVERT_VSCODE_TO_MONACO, CONVERT_MONACO_TO_VSCODE];
300
+ mappings['vscode.executeCodeActionProvider'] = ['vscode.executeCodeActionProvider', CONVERT_VSCODE_TO_MONACO, CONVERT_MONACO_TO_VSCODE];
300
301
  mappings['vscode.prepareCallHierarchy'] = ['vscode.prepareCallHierarchy', CONVERT_VSCODE_TO_MONACO, CONVERT_MONACO_TO_VSCODE];
301
302
  mappings['vscode.provideIncomingCalls'] = ['vscode.provideIncomingCalls', CONVERT_VSCODE_TO_MONACO, CONVERT_MONACO_TO_VSCODE];
302
303
  mappings['vscode.provideOutgoingCalls'] = ['vscode.provideOutgoingCalls', CONVERT_VSCODE_TO_MONACO, CONVERT_MONACO_TO_VSCODE];