@theia/plugin-ext 1.43.1 → 1.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/lib/common/plugin-api-rpc.d.ts +11 -1
  2. package/lib/common/plugin-api-rpc.d.ts.map +1 -1
  3. package/lib/common/plugin-api-rpc.js.map +1 -1
  4. package/lib/common/plugin-protocol.d.ts +9 -2
  5. package/lib/common/plugin-protocol.d.ts.map +1 -1
  6. package/lib/common/plugin-protocol.js.map +1 -1
  7. package/lib/common/proxy-handler.d.ts.map +1 -1
  8. package/lib/common/proxy-handler.js +3 -1
  9. package/lib/common/proxy-handler.js.map +1 -1
  10. package/lib/common/test-types.d.ts +9 -0
  11. package/lib/common/test-types.d.ts.map +1 -1
  12. package/lib/common/test-types.js +36 -1
  13. package/lib/common/test-types.js.map +1 -1
  14. package/lib/hosted/browser/hosted-plugin.d.ts +2 -0
  15. package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
  16. package/lib/hosted/browser/hosted-plugin.js +54 -6
  17. package/lib/hosted/browser/hosted-plugin.js.map +1 -1
  18. package/lib/hosted/node/hosted-plugin-deployer-handler.d.ts +1 -0
  19. package/lib/hosted/node/hosted-plugin-deployer-handler.d.ts.map +1 -1
  20. package/lib/hosted/node/hosted-plugin-deployer-handler.js +6 -0
  21. package/lib/hosted/node/hosted-plugin-deployer-handler.js.map +1 -1
  22. package/lib/hosted/node/plugin-activation-events.d.ts.map +1 -1
  23. package/lib/hosted/node/plugin-activation-events.js +1 -1
  24. package/lib/hosted/node/plugin-activation-events.js.map +1 -1
  25. package/lib/hosted/node/scanners/scanner-theia.d.ts +0 -3
  26. package/lib/hosted/node/scanners/scanner-theia.d.ts.map +1 -1
  27. package/lib/hosted/node/scanners/scanner-theia.js +11 -94
  28. package/lib/hosted/node/scanners/scanner-theia.js.map +1 -1
  29. package/lib/main/browser/debug/plugin-debug-service.d.ts +3 -0
  30. package/lib/main/browser/debug/plugin-debug-service.d.ts.map +1 -1
  31. package/lib/main/browser/debug/plugin-debug-service.js +85 -1
  32. package/lib/main/browser/debug/plugin-debug-service.js.map +1 -1
  33. package/lib/main/browser/languages-main.d.ts.map +1 -1
  34. package/lib/main/browser/languages-main.js +1 -0
  35. package/lib/main/browser/languages-main.js.map +1 -1
  36. package/lib/main/browser/menus/plugin-menu-command-adapter.d.ts +1 -0
  37. package/lib/main/browser/menus/plugin-menu-command-adapter.d.ts.map +1 -1
  38. package/lib/main/browser/menus/plugin-menu-command-adapter.js +30 -0
  39. package/lib/main/browser/menus/plugin-menu-command-adapter.js.map +1 -1
  40. package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts +2 -2
  41. package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts.map +1 -1
  42. package/lib/main/browser/menus/vscode-theia-menu-mappings.js +6 -1
  43. package/lib/main/browser/menus/vscode-theia-menu-mappings.js.map +1 -1
  44. package/lib/main/browser/notebooks/notebook-documents-and-editors-main.d.ts +4 -2
  45. package/lib/main/browser/notebooks/notebook-documents-and-editors-main.d.ts.map +1 -1
  46. package/lib/main/browser/notebooks/notebook-documents-and-editors-main.js +34 -21
  47. package/lib/main/browser/notebooks/notebook-documents-and-editors-main.js.map +1 -1
  48. package/lib/main/browser/notebooks/notebook-documents-main.d.ts.map +1 -1
  49. package/lib/main/browser/notebooks/notebook-documents-main.js +8 -9
  50. package/lib/main/browser/notebooks/notebook-documents-main.js.map +1 -1
  51. package/lib/main/browser/notebooks/notebook-dto.d.ts +3 -0
  52. package/lib/main/browser/notebooks/notebook-dto.d.ts.map +1 -1
  53. package/lib/main/browser/notebooks/notebook-dto.js +27 -34
  54. package/lib/main/browser/notebooks/notebook-dto.js.map +1 -1
  55. package/lib/main/browser/notebooks/notebook-kernels-main.js +3 -3
  56. package/lib/main/browser/notebooks/notebook-kernels-main.js.map +1 -1
  57. package/lib/main/browser/notebooks/notebooks-main.d.ts +12 -1
  58. package/lib/main/browser/notebooks/notebooks-main.d.ts.map +1 -1
  59. package/lib/main/browser/notebooks/notebooks-main.js.map +1 -1
  60. package/lib/main/browser/notebooks/renderers/cell-output-webview.d.ts +1 -2
  61. package/lib/main/browser/notebooks/renderers/cell-output-webview.d.ts.map +1 -1
  62. package/lib/main/browser/notebooks/renderers/cell-output-webview.js +1 -1
  63. package/lib/main/browser/notebooks/renderers/cell-output-webview.js.map +1 -1
  64. package/lib/main/browser/plugin-contribution-handler.d.ts +2 -0
  65. package/lib/main/browser/plugin-contribution-handler.d.ts.map +1 -1
  66. package/lib/main/browser/plugin-contribution-handler.js +10 -0
  67. package/lib/main/browser/plugin-contribution-handler.js.map +1 -1
  68. package/lib/main/browser/plugin-icon-theme-service.d.ts +12 -1
  69. package/lib/main/browser/plugin-icon-theme-service.d.ts.map +1 -1
  70. package/lib/main/browser/plugin-icon-theme-service.js +44 -8
  71. package/lib/main/browser/plugin-icon-theme-service.js.map +1 -1
  72. package/lib/main/browser/plugin-shared-style.d.ts +5 -1
  73. package/lib/main/browser/plugin-shared-style.d.ts.map +1 -1
  74. package/lib/main/browser/plugin-shared-style.js +33 -16
  75. package/lib/main/browser/plugin-shared-style.js.map +1 -1
  76. package/lib/main/browser/terminal-main.d.ts +1 -0
  77. package/lib/main/browser/terminal-main.d.ts.map +1 -1
  78. package/lib/main/browser/terminal-main.js +5 -0
  79. package/lib/main/browser/terminal-main.js.map +1 -1
  80. package/lib/main/browser/text-editor-main.d.ts.map +1 -1
  81. package/lib/main/browser/text-editor-main.js +10 -0
  82. package/lib/main/browser/text-editor-main.js.map +1 -1
  83. package/lib/main/browser/webview/webview.d.ts +20 -1
  84. package/lib/main/browser/webview/webview.d.ts.map +1 -1
  85. package/lib/main/browser/webview/webview.js +38 -1
  86. package/lib/main/browser/webview/webview.js.map +1 -1
  87. package/lib/main/node/plugin-deployer-contribution.d.ts +1 -1
  88. package/lib/main/node/plugin-deployer-contribution.d.ts.map +1 -1
  89. package/lib/main/node/plugin-deployer-contribution.js +2 -1
  90. package/lib/main/node/plugin-deployer-contribution.js.map +1 -1
  91. package/lib/main/node/plugin-deployer-impl.d.ts +1 -1
  92. package/lib/main/node/plugin-deployer-impl.d.ts.map +1 -1
  93. package/lib/main/node/plugin-deployer-impl.js +3 -2
  94. package/lib/main/node/plugin-deployer-impl.js.map +1 -1
  95. package/lib/main/node/plugin-ext-backend-module.d.ts.map +1 -1
  96. package/lib/main/node/plugin-ext-backend-module.js +3 -0
  97. package/lib/main/node/plugin-ext-backend-module.js.map +1 -1
  98. package/lib/main/node/plugin-mgmt-cli-contribution.d.ts +13 -0
  99. package/lib/main/node/plugin-mgmt-cli-contribution.d.ts.map +1 -0
  100. package/lib/main/node/plugin-mgmt-cli-contribution.js +71 -0
  101. package/lib/main/node/plugin-mgmt-cli-contribution.js.map +1 -0
  102. package/lib/plugin/command-registry.d.ts.map +1 -1
  103. package/lib/plugin/command-registry.js +9 -3
  104. package/lib/plugin/command-registry.js.map +1 -1
  105. package/lib/plugin/env.d.ts +0 -3
  106. package/lib/plugin/env.d.ts.map +1 -1
  107. package/lib/plugin/env.js +0 -6
  108. package/lib/plugin/env.js.map +1 -1
  109. package/lib/plugin/languages-utils.d.ts +2 -1
  110. package/lib/plugin/languages-utils.d.ts.map +1 -1
  111. package/lib/plugin/languages-utils.js +14 -1
  112. package/lib/plugin/languages-utils.js.map +1 -1
  113. package/lib/plugin/languages.d.ts.map +1 -1
  114. package/lib/plugin/languages.js +2 -1
  115. package/lib/plugin/languages.js.map +1 -1
  116. package/lib/plugin/notebook/notebook-document.js +3 -3
  117. package/lib/plugin/notebook/notebook-document.js.map +1 -1
  118. package/lib/plugin/notebook/notebooks.d.ts.map +1 -1
  119. package/lib/plugin/notebook/notebooks.js +7 -4
  120. package/lib/plugin/notebook/notebooks.js.map +1 -1
  121. package/lib/plugin/plugin-context.d.ts.map +1 -1
  122. package/lib/plugin/plugin-context.js +5 -1
  123. package/lib/plugin/plugin-context.js.map +1 -1
  124. package/lib/plugin/plugin-manager.d.ts +1 -1
  125. package/lib/plugin/plugin-manager.d.ts.map +1 -1
  126. package/lib/plugin/plugin-manager.js +4 -24
  127. package/lib/plugin/plugin-manager.js.map +1 -1
  128. package/lib/plugin/status-bar/status-bar-item.d.ts.map +1 -1
  129. package/lib/plugin/terminal-ext.d.ts +5 -0
  130. package/lib/plugin/terminal-ext.d.ts.map +1 -1
  131. package/lib/plugin/terminal-ext.js +11 -0
  132. package/lib/plugin/terminal-ext.js.map +1 -1
  133. package/lib/plugin/tests.d.ts +6 -1
  134. package/lib/plugin/tests.d.ts.map +1 -1
  135. package/lib/plugin/tests.js +22 -0
  136. package/lib/plugin/tests.js.map +1 -1
  137. package/lib/plugin/text-editor.d.ts +6 -2
  138. package/lib/plugin/text-editor.d.ts.map +1 -1
  139. package/lib/plugin/text-editor.js +57 -2
  140. package/lib/plugin/text-editor.js.map +1 -1
  141. package/lib/plugin/type-converters.d.ts +1 -12
  142. package/lib/plugin/type-converters.d.ts.map +1 -1
  143. package/lib/plugin/type-converters.js +3 -121
  144. package/lib/plugin/type-converters.js.map +1 -1
  145. package/lib/plugin/types-impl.d.ts +23 -0
  146. package/lib/plugin/types-impl.d.ts.map +1 -1
  147. package/lib/plugin/types-impl.js +36 -4
  148. package/lib/plugin/types-impl.js.map +1 -1
  149. package/lib/plugin/window-state.d.ts.map +1 -1
  150. package/lib/plugin/window-state.js +3 -4
  151. package/lib/plugin/window-state.js.map +1 -1
  152. package/package.json +29 -29
  153. package/src/common/plugin-api-rpc.ts +12 -1
  154. package/src/common/plugin-protocol.ts +9 -2
  155. package/src/common/proxy-handler.ts +3 -1
  156. package/src/common/test-types.ts +20 -0
  157. package/src/hosted/browser/hosted-plugin.ts +51 -6
  158. package/src/hosted/node/hosted-plugin-deployer-handler.ts +7 -0
  159. package/src/hosted/node/plugin-activation-events.ts +10 -9
  160. package/src/hosted/node/scanners/scanner-theia.ts +10 -101
  161. package/src/main/browser/debug/plugin-debug-service.ts +91 -2
  162. package/src/main/browser/languages-main.ts +1 -0
  163. package/src/main/browser/menus/plugin-menu-command-adapter.ts +30 -0
  164. package/src/main/browser/menus/vscode-theia-menu-mappings.ts +7 -2
  165. package/src/main/browser/notebooks/notebook-documents-and-editors-main.ts +36 -22
  166. package/src/main/browser/notebooks/notebook-documents-main.ts +11 -12
  167. package/src/main/browser/notebooks/notebook-dto.ts +24 -34
  168. package/src/main/browser/notebooks/notebook-kernels-main.ts +1 -1
  169. package/src/main/browser/notebooks/notebooks-main.ts +13 -2
  170. package/src/main/browser/notebooks/renderers/cell-output-webview.tsx +3 -3
  171. package/src/main/browser/plugin-contribution-handler.ts +9 -0
  172. package/src/main/browser/plugin-icon-theme-service.ts +46 -12
  173. package/src/main/browser/plugin-shared-style.ts +37 -17
  174. package/src/main/browser/terminal-main.ts +7 -0
  175. package/src/main/browser/text-editor-main.ts +9 -0
  176. package/src/main/browser/webview/pre/host.js +1 -1
  177. package/src/main/browser/webview/pre/main.js +84 -34
  178. package/src/main/browser/webview/webview.ts +49 -1
  179. package/src/main/node/plugin-deployer-contribution.ts +3 -2
  180. package/src/main/node/plugin-deployer-impl.ts +4 -3
  181. package/src/main/node/plugin-ext-backend-module.ts +4 -0
  182. package/src/main/node/plugin-mgmt-cli-contribution.ts +64 -0
  183. package/src/plugin/command-registry.ts +8 -3
  184. package/src/plugin/env.ts +0 -8
  185. package/src/plugin/languages-utils.ts +13 -1
  186. package/src/plugin/languages.ts +3 -2
  187. package/src/plugin/notebook/notebook-document.ts +8 -8
  188. package/src/plugin/notebook/notebooks.ts +6 -4
  189. package/src/plugin/plugin-context.ts +6 -1
  190. package/src/plugin/plugin-manager.ts +5 -25
  191. package/src/plugin/status-bar/status-bar-item.ts +1 -1
  192. package/src/plugin/terminal-ext.ts +15 -0
  193. package/src/plugin/tests.ts +25 -1
  194. package/src/plugin/text-editor.ts +64 -4
  195. package/src/plugin/type-converters.ts +3 -123
  196. package/src/plugin/types-impl.ts +33 -0
  197. package/src/plugin/window-state.ts +4 -4
@@ -23,7 +23,7 @@ import { interfaces } from '@theia/core/shared/inversify';
23
23
  import { UriComponents } from '@theia/core/lib/common/uri';
24
24
  import { NotebookEditorWidget, NotebookService, NotebookEditorWidgetService } from '@theia/notebook/lib/browser';
25
25
  import { NotebookModel } from '@theia/notebook/lib/browser/view-model/notebook-model';
26
- import { MAIN_RPC_CONTEXT, NotebookDocumentsAndEditorsDelta, NotebookDocumentsAndEditorsMain, NotebookModelAddedData, NotebooksExt } from '../../../common';
26
+ import { MAIN_RPC_CONTEXT, NotebookDocumentsAndEditorsDelta, NotebookDocumentsAndEditorsMain, NotebookEditorAddData, NotebookModelAddedData, NotebooksExt } from '../../../common';
27
27
  import { RPCProtocol } from '../../../common/rpc-protocol';
28
28
  import { NotebookDto } from './notebook-dto';
29
29
  import { WidgetManager } from '@theia/core/lib/browser';
@@ -31,6 +31,7 @@ import { NotebookEditorsMainImpl } from './notebook-editors-main';
31
31
  import { NotebookDocumentsMainImpl } from './notebook-documents-main';
32
32
  import { diffMaps, diffSets } from '../../../common/collections';
33
33
  import { Mutex } from 'async-mutex';
34
+ import throttle = require('@theia/core/shared/lodash.throttle');
34
35
 
35
36
  interface NotebookAndEditorDelta {
36
37
  removedDocuments: UriComponents[];
@@ -42,7 +43,7 @@ interface NotebookAndEditorDelta {
42
43
  }
43
44
 
44
45
  class NotebookAndEditorState {
45
- static delta(before: NotebookAndEditorState | undefined, after: NotebookAndEditorState): NotebookAndEditorDelta {
46
+ static computeDelta(before: NotebookAndEditorState | undefined, after: NotebookAndEditorState): NotebookAndEditorDelta {
46
47
  if (!before) {
47
48
  return {
48
49
  addedDocuments: [...after.documents],
@@ -106,12 +107,12 @@ export class NotebooksAndEditorsMain implements NotebookDocumentsAndEditorsMain
106
107
  this.notebookEditorService = container.get(NotebookEditorWidgetService);
107
108
  this.WidgetManager = container.get(WidgetManager);
108
109
 
109
- this.notebookService.onDidAddNotebookDocument(async () => this.updateState(), this, this.disposables);
110
- this.notebookService.onDidRemoveNotebookDocument(async () => this.updateState(), this, this.disposables);
110
+ this.notebookService.onDidAddNotebookDocument(async () => this.throttleStateUpdate(), this, this.disposables);
111
+ this.notebookService.onDidRemoveNotebookDocument(async () => this.throttleStateUpdate(), this, this.disposables);
111
112
  // this.WidgetManager.onActiveEditorChanged(() => this.updateState(), this, this.disposables);
112
113
  this.notebookEditorService.onDidAddNotebookEditor(async editor => this.handleEditorAdd(editor), this, this.disposables);
113
114
  this.notebookEditorService.onDidRemoveNotebookEditor(async editor => this.handleEditorRemove(editor), this, this.disposables);
114
- this.notebookEditorService.onDidChangeFocusedEditor(async editor => this.updateState(editor), this, this.disposables);
115
+ this.notebookEditorService.onDidChangeFocusedEditor(async editor => this.throttleStateUpdate(editor), this, this.disposables);
115
116
  }
116
117
 
117
118
  dispose(): void {
@@ -129,16 +130,18 @@ export class NotebooksAndEditorsMain implements NotebookDocumentsAndEditorsMain
129
130
  } else {
130
131
  this.editorListeners.set(editor.id, [disposable]);
131
132
  }
132
- await this.updateState();
133
+ await this.throttleStateUpdate();
133
134
  }
134
135
 
135
136
  private handleEditorRemove(editor: NotebookEditorWidget): void {
136
137
  const listeners = this.editorListeners.get(editor.id);
137
138
  listeners?.forEach(listener => listener.dispose());
138
139
  this.editorListeners.delete(editor.id);
139
- this.updateState();
140
+ this.throttleStateUpdate();
140
141
  }
141
142
 
143
+ private throttleStateUpdate = throttle((focusedEditor?: NotebookEditorWidget) => this.updateState(focusedEditor), 100);
144
+
142
145
  private async updateState(focusedEditor?: NotebookEditorWidget): Promise<void> {
143
146
  await this.updateMutex.runExclusive(async () => this.doUpdateState(focusedEditor));
144
147
  }
@@ -148,10 +151,8 @@ export class NotebooksAndEditorsMain implements NotebookDocumentsAndEditorsMain
148
151
  const editors = new Map<string, NotebookEditorWidget>();
149
152
  const visibleEditorsMap = new Map<string, NotebookEditorWidget>();
150
153
 
151
- for (const editor of this.notebookEditorService.listNotebookEditors()) {
152
- if (editor.model) {
153
- editors.set(editor.id, editor);
154
- }
154
+ for (const editor of this.notebookEditorService.getNotebookEditors()) {
155
+ editors.set(editor.id, editor);
155
156
  }
156
157
 
157
158
  const activeNotebookEditor = this.notebookEditorService.focusedEditor;
@@ -167,7 +168,7 @@ export class NotebooksAndEditorsMain implements NotebookDocumentsAndEditorsMain
167
168
 
168
169
  const notebookEditors = this.WidgetManager.getWidgets(NotebookEditorWidget.ID) as NotebookEditorWidget[];
169
170
  for (const notebookEditor of notebookEditors) {
170
- if (notebookEditor?.model && editors.has(notebookEditor.id) && notebookEditor.isVisible) {
171
+ if (editors.has(notebookEditor.id) && notebookEditor.isVisible) {
171
172
  visibleEditorsMap.set(notebookEditor.id, notebookEditor);
172
173
  }
173
174
  }
@@ -176,12 +177,12 @@ export class NotebooksAndEditorsMain implements NotebookDocumentsAndEditorsMain
176
177
  new Set(this.notebookService.listNotebookDocuments()),
177
178
  editors,
178
179
  activeEditor, visibleEditorsMap);
179
- await this.onDelta(NotebookAndEditorState.delta(this.currentState, newState));
180
+ await this.onDelta(NotebookAndEditorState.computeDelta(this.currentState, newState));
180
181
  this.currentState = newState;
181
182
  }
182
183
 
183
184
  private async onDelta(delta: NotebookAndEditorDelta): Promise<void> {
184
- if (NotebooksAndEditorsMain._isDeltaEmpty(delta)) {
185
+ if (NotebooksAndEditorsMain.isDeltaEmpty(delta)) {
185
186
  return;
186
187
  }
187
188
 
@@ -191,7 +192,7 @@ export class NotebooksAndEditorsMain implements NotebookDocumentsAndEditorsMain
191
192
  newActiveEditor: delta.newActiveEditor,
192
193
  visibleEditors: delta.visibleEditors,
193
194
  addedDocuments: delta.addedDocuments.map(NotebooksAndEditorsMain.asModelAddData),
194
- // addedEditors: delta.addedEditors.map(this.asEditorAddData, this),
195
+ addedEditors: delta.addedEditors.map(NotebooksAndEditorsMain.asEditorAddData),
195
196
  };
196
197
 
197
198
  // send to extension FIRST
@@ -204,23 +205,23 @@ export class NotebooksAndEditorsMain implements NotebookDocumentsAndEditorsMain
204
205
  this.notebookEditorsMain.handleEditorsAdded(delta.addedEditors);
205
206
  }
206
207
 
207
- private static _isDeltaEmpty(delta: NotebookAndEditorDelta): boolean {
208
- if (delta.addedDocuments !== undefined && delta.addedDocuments.length > 0) {
208
+ private static isDeltaEmpty(delta: NotebookAndEditorDelta): boolean {
209
+ if (delta.addedDocuments?.length) {
209
210
  return false;
210
211
  }
211
- if (delta.removedDocuments !== undefined && delta.removedDocuments.length > 0) {
212
+ if (delta.removedDocuments?.length) {
212
213
  return false;
213
214
  }
214
- if (delta.addedEditors !== undefined && delta.addedEditors.length > 0) {
215
+ if (delta.addedEditors?.length) {
215
216
  return false;
216
217
  }
217
- if (delta.removedEditors !== undefined && delta.removedEditors.length > 0) {
218
+ if (delta.removedEditors?.length) {
218
219
  return false;
219
220
  }
220
- if (delta.visibleEditors !== undefined && delta.visibleEditors.length > 0) {
221
+ if (delta.visibleEditors?.length) {
221
222
  return false;
222
223
  }
223
- if (delta.newActiveEditor !== undefined) {
224
+ if (delta.newActiveEditor) {
224
225
  return false;
225
226
  }
226
227
  return true;
@@ -235,4 +236,17 @@ export class NotebooksAndEditorsMain implements NotebookDocumentsAndEditorsMain
235
236
  cells: e.cells.map(NotebookDto.toNotebookCellDto)
236
237
  };
237
238
  }
239
+
240
+ private static asEditorAddData(notebookEditor: NotebookEditorWidget): NotebookEditorAddData {
241
+ const uri = notebookEditor.getResourceUri();
242
+ if (!uri) {
243
+ throw new Error('Notebook editor without resource URI');
244
+ }
245
+ return {
246
+ id: notebookEditor.id,
247
+ documentUri: uri.toComponents(),
248
+ selections: [],
249
+ visibleRanges: []
250
+ };
251
+ }
238
252
  }
@@ -20,7 +20,7 @@ import { interfaces } from '@theia/core/shared/inversify';
20
20
  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
- import { MAIN_RPC_CONTEXT, NotebookCellDto, NotebookCellsChangedEventDto, NotebookDataDto, NotebookDocumentsExt, NotebookDocumentsMain } from '../../../common';
23
+ import { MAIN_RPC_CONTEXT, NotebookCellsChangedEventDto, NotebookDataDto, NotebookDocumentsExt, NotebookDocumentsMain } from '../../../common';
24
24
  import { RPCProtocol } from '../../../common/rpc-protocol';
25
25
  import { NotebookDto } from './notebook-dto';
26
26
 
@@ -54,23 +54,22 @@ export class NotebookDocumentsMainImpl implements NotebookDocumentsMain {
54
54
 
55
55
  handleNotebooksAdded(notebooks: readonly NotebookModel[]): void {
56
56
 
57
- for (const textModel of notebooks) {
58
- const disposableStore = new DisposableCollection();
59
- disposableStore.push(textModel.onDidChangeContent(event => {
57
+ for (const notebook of notebooks) {
58
+ const listener = notebook.onDidChangeContent(events => {
60
59
 
61
60
  const eventDto: NotebookCellsChangedEventDto = {
62
61
  versionId: 1, // TODO implement version ID support
63
62
  rawEvents: []
64
63
  };
65
64
 
66
- for (const e of event.rawEvents) {
65
+ for (const e of events) {
67
66
 
68
67
  switch (e.kind) {
69
68
  case NotebookCellsChangeType.ModelChange:
70
69
  eventDto.rawEvents.push({
71
70
  kind: e.kind,
72
71
  changes: e.changes.map(diff =>
73
- [diff[0], diff[1], diff[2].map(NotebookDto.toNotebookCellDto)] as [number, number, NotebookCellDto[]])
72
+ ({ ...diff, newItems: diff.newItems.map(NotebookDto.toNotebookCellDto) }))
74
73
  });
75
74
  break;
76
75
  case NotebookCellsChangeType.Move:
@@ -106,20 +105,20 @@ export class NotebookDocumentsMainImpl implements NotebookDocumentsMain {
106
105
  }
107
106
  }
108
107
 
109
- const hasDocumentMetadataChangeEvent = event.rawEvents.find(e => e.kind === NotebookCellsChangeType.ChangeDocumentMetadata);
108
+ const hasDocumentMetadataChangeEvent = events.find(e => e.kind === NotebookCellsChangeType.ChangeDocumentMetadata);
110
109
 
111
110
  // using the model resolver service to know if the model is dirty or not.
112
111
  // assuming this is the first listener it can mean that at first the model
113
112
  // is marked as dirty and that another event is fired
114
113
  this.proxy.$acceptModelChanged(
115
- textModel.uri.toComponents(),
114
+ notebook.uri.toComponents(),
116
115
  eventDto,
117
- textModel.isDirty(),
118
- hasDocumentMetadataChangeEvent ? textModel.metadata : undefined
116
+ notebook.isDirty(),
117
+ hasDocumentMetadataChangeEvent ? notebook.metadata : undefined
119
118
  );
120
- }));
119
+ });
121
120
 
122
- this.documentEventListenersMapping.set(textModel.uri.toString(), disposableStore);
121
+ this.documentEventListenersMapping.set(notebook.uri.toString(), new DisposableCollection(listener));
123
122
  }
124
123
  }
125
124
 
@@ -18,6 +18,8 @@ import { OS } from '@theia/core';
18
18
  import * as notebookCommon from '@theia/notebook/lib/common';
19
19
  import { NotebookCellModel } from '@theia/notebook/lib/browser/view-model/notebook-cell-model';
20
20
  import * as rpc from '../../../common';
21
+ import { CellExecutionUpdateType } from '@theia/notebook/lib/common';
22
+ import { CellExecuteUpdate, CellExecutionComplete } from '@theia/notebook/lib/browser';
21
23
 
22
24
  export namespace NotebookDto {
23
25
 
@@ -102,40 +104,28 @@ export namespace NotebookDto {
102
104
  };
103
105
  }
104
106
 
105
- // export function fromCellExecuteUpdateDto(data: extHostProtocol.ICellExecuteUpdateDto): ICellExecuteUpdate {
106
- // if (data.editType === CellExecutionUpdateType.Output) {
107
- // return {
108
- // editType: data.editType,
109
- // cellHandle: data.cellHandle,
110
- // append: data.append,
111
- // outputs: data.outputs.map(fromNotebookOutputDto)
112
- // };
113
- // } else if (data.editType === CellExecutionUpdateType.OutputItems) {
114
- // return {
115
- // editType: data.editType,
116
- // append: data.append,
117
- // outputId: data.outputId,
118
- // items: data.items.map(fromNotebookOutputItemDto)
119
- // };
120
- // } else {
121
- // return data;
122
- // }
123
- // }
107
+ export function fromCellExecuteUpdateDto(data: rpc.CellExecuteUpdateDto): CellExecuteUpdate {
108
+ if (data.editType === CellExecutionUpdateType.Output) {
109
+ return {
110
+ editType: data.editType,
111
+ cellHandle: data.cellHandle,
112
+ append: data.append,
113
+ outputs: data.outputs.map(fromNotebookOutputDto)
114
+ };
115
+ } else if (data.editType === CellExecutionUpdateType.OutputItems) {
116
+ return {
117
+ editType: data.editType,
118
+ outputId: data.outputId,
119
+ append: data.append,
120
+ items: data.items.map(fromNotebookOutputItemDto)
121
+ };
122
+ } else {
123
+ return data;
124
+ }
125
+ }
124
126
 
125
- // export function fromCellExecuteCompleteDto(data: extHostProtocol.ICellExecutionCompleteDto): ICellExecutionComplete {
126
- // return data;
127
- // }
127
+ export function fromCellExecuteCompleteDto(data: rpc.CellExecutionCompleteDto): CellExecutionComplete {
128
+ return data;
129
+ }
128
130
 
129
- // export function fromCellEditOperationDto(edit: extHostProtocol.ICellEditOperationDto): notebookCommon.ICellEditOperation {
130
- // if (edit.editType === notebookCommon.CellEditType.Replace) {
131
- // return {
132
- // editType: edit.editType,
133
- // index: edit.index,
134
- // count: edit.count,
135
- // cells: edit.cells.map(fromNotebookCellDataDto)
136
- // };
137
- // } else {
138
- // return edit;
139
- // }
140
- // }
141
131
  }
@@ -27,7 +27,7 @@ import { CellExecution, NotebookExecutionStateService, NotebookKernelChangeEvent
27
27
  import { combinedDisposable } from '@theia/monaco-editor-core/esm/vs/base/common/lifecycle';
28
28
  import { interfaces } from '@theia/core/shared/inversify';
29
29
  import { NotebookKernelSourceAction } from '@theia/notebook/lib/common';
30
- import { NotebookDto } from '../../../plugin/type-converters';
30
+ import { NotebookDto } from './notebook-dto';
31
31
 
32
32
  abstract class NotebookKernel {
33
33
  private readonly onDidChangeEmitter = new Emitter<NotebookKernelChangeEvent>();
@@ -14,9 +14,9 @@
14
14
  // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
15
  // *****************************************************************************
16
16
 
17
- import { CancellationToken, DisposableCollection, Emitter } from '@theia/core';
17
+ import { CancellationToken, DisposableCollection, Emitter, Event } from '@theia/core';
18
18
  import { BinaryBuffer } from '@theia/core/lib/common/buffer';
19
- import { NotebookCellStatusBarItemList, NotebookCellStatusBarItemProvider, NotebookData, TransientOptions } from '@theia/notebook/lib/common';
19
+ import { NotebookCellStatusBarItem, NotebookData, TransientOptions } from '@theia/notebook/lib/common';
20
20
  import { NotebookService } from '@theia/notebook/lib/browser';
21
21
  import { Disposable } from '@theia/plugin';
22
22
  import { MAIN_RPC_CONTEXT, NotebooksExt, NotebooksMain } from '../../../common';
@@ -25,6 +25,17 @@ import { NotebookDto } from './notebook-dto';
25
25
  import { UriComponents } from '@theia/core/lib/common/uri';
26
26
  import { HostedPluginSupport } from '../../../hosted/browser/hosted-plugin';
27
27
 
28
+ export interface NotebookCellStatusBarItemList {
29
+ items: NotebookCellStatusBarItem[];
30
+ dispose?(): void;
31
+ }
32
+
33
+ export interface NotebookCellStatusBarItemProvider {
34
+ viewType: string;
35
+ onDidChangeStatusBarItems?: Event<void>;
36
+ provideCellStatusBarItems(uri: UriComponents, index: number, token: CancellationToken): Promise<NotebookCellStatusBarItemList | undefined>;
37
+ }
38
+
28
39
  export class NotebooksMainImpl implements NotebooksMain {
29
40
 
30
41
  private readonly disposables = new DisposableCollection();
@@ -20,7 +20,7 @@
20
20
 
21
21
  import * as React from '@theia/core/shared/react';
22
22
  import { inject, injectable, interfaces, postConstruct } from '@theia/core/shared/inversify';
23
- import { NotebookRendererMessagingService, CellOutputWebview, NotebookRendererRegistry, NotebookEditorWidgetService } from '@theia/notebook/lib/browser';
23
+ import { NotebookRendererMessagingService, CellOutputWebview, NotebookRendererRegistry, NotebookEditorWidgetService, NotebookCellOutputsSplice } from '@theia/notebook/lib/browser';
24
24
  import { v4 } from 'uuid';
25
25
  import { NotebookCellModel } from '@theia/notebook/lib/browser/view-model/notebook-cell-model';
26
26
  import { WebviewWidget } from '../../webview/webview';
@@ -28,7 +28,7 @@ import { Message, WidgetManager } from '@theia/core/lib/browser';
28
28
  import { outputWebviewPreload, PreloadContext } from './output-webview-internal';
29
29
  import { WorkspaceTrustService } from '@theia/workspace/lib/browser';
30
30
  import { ChangePreferredMimetypeMessage, FromWebviewMessage, OutputChangedMessage } from './webview-communication';
31
- import { CellUri, NotebookCellOutputsSplice } from '@theia/notebook/lib/common';
31
+ import { CellUri } from '@theia/notebook/lib/common';
32
32
  import { Disposable, DisposableCollection, nls, QuickPickService } from '@theia/core';
33
33
  import { NotebookCellOutputModel } from '@theia/notebook/lib/browser/view-model/notebook-cell-output-model';
34
34
 
@@ -76,7 +76,7 @@ export class CellOutputWebviewImpl implements CellOutputWebview, Disposable {
76
76
  protected async init(): Promise<void> {
77
77
  this.cell.onDidChangeOutputs(outputChange => this.updateOutput(outputChange));
78
78
  this.cell.onDidChangeOutputItems(output => {
79
- this.updateOutput({start: this.cell.outputs.findIndex(o => o.getData().outputId === o.outputId), deleteCount: 1, newOutputs: [output]});
79
+ this.updateOutput({start: this.cell.outputs.findIndex(o => o.outputId === output.outputId), deleteCount: 1, newOutputs: [output]});
80
80
  });
81
81
 
82
82
  this.webviewWidget = await this.widgetManager.getOrCreateWidget(WebviewWidget.FACTORY_ID, { id: this.id });
@@ -53,6 +53,7 @@ import { TerminalWidget } from '@theia/terminal/lib/browser/base/terminal-widget
53
53
  import { TerminalService } from '@theia/terminal/lib/browser/base/terminal-service';
54
54
  import { PluginTerminalRegistry } from './plugin-terminal-registry';
55
55
  import { ContextKeyService } from '@theia/core/lib/browser/context-key-service';
56
+ import { LanguageService } from '@theia/core/lib/browser/language-service';
56
57
 
57
58
  @injectable()
58
59
  export class PluginContributionHandler {
@@ -89,6 +90,9 @@ export class PluginContributionHandler {
89
90
  @inject(CommandRegistry)
90
91
  protected readonly commands: CommandRegistry;
91
92
 
93
+ @inject(LanguageService)
94
+ protected readonly languageService: LanguageService;
95
+
92
96
  @inject(PluginSharedStyle)
93
97
  protected readonly style: PluginSharedStyle;
94
98
 
@@ -195,6 +199,11 @@ export class PluginContributionHandler {
195
199
  firstLine: lang.firstLine,
196
200
  mimetypes: lang.mimetypes
197
201
  });
202
+ if (lang.icon) {
203
+ const languageIcon = this.style.toFileIconClass(lang.icon);
204
+ pushContribution(`language.${lang.id}.icon`, () => languageIcon);
205
+ pushContribution(`language.${lang.id}.iconRegistration`, () => this.languageService.registerIcon(lang.id, languageIcon.object.iconClass));
206
+ }
198
207
  const langConfiguration = lang.configuration;
199
208
  if (langConfiguration) {
200
209
  pushContribution(`language.${lang.id}.configuration`, () => monaco.languages.setLanguageConfiguration(lang.id, {
@@ -39,6 +39,8 @@ import { FileStat, FileChangeType } from '@theia/filesystem/lib/common/files';
39
39
  import { WorkspaceService } from '@theia/workspace/lib/browser';
40
40
  import { StandaloneServices } from '@theia/monaco-editor-core/esm/vs/editor/standalone/browser/standaloneServices';
41
41
  import { ILanguageService } from '@theia/monaco-editor-core/esm/vs/editor/common/languages/language';
42
+ import { LanguageService } from '@theia/core/lib/browser/language-service';
43
+ import { DEFAULT_ICON_SIZE, PLUGIN_FILE_ICON_CLASS } from './plugin-shared-style';
42
44
 
43
45
  export interface PluginIconDefinition {
44
46
  iconPath: string;
@@ -79,6 +81,7 @@ export interface PluginIconThemeDocument extends PluginIconsAssociation {
79
81
  light?: PluginIconsAssociation;
80
82
  highContrast?: PluginIconsAssociation;
81
83
  hidesExplorerArrows?: boolean;
84
+ showLanguageModeIcons?: boolean;
82
85
  }
83
86
 
84
87
  export const PluginIconThemeFactory = Symbol('PluginIconThemeFactory');
@@ -96,8 +99,14 @@ export class PluginIconThemeDefinition implements IconThemeDefinition, IconTheme
96
99
  hasFileIcons?: boolean;
97
100
  hasFolderIcons?: boolean;
98
101
  hidesExplorerArrows?: boolean;
102
+ showLanguageModeIcons?: boolean;
99
103
  }
100
104
 
105
+ class PluginLanguageIconInfo {
106
+ hasSpecificFileIcons: boolean = false;
107
+ coveredLanguages: { [languageId: string]: boolean } = {};
108
+ };
109
+
101
110
  @injectable()
102
111
  export class PluginIconTheme extends PluginIconThemeDefinition implements IconTheme, Disposable {
103
112
 
@@ -113,6 +122,9 @@ export class PluginIconTheme extends PluginIconThemeDefinition implements IconTh
113
122
  @inject(WorkspaceService)
114
123
  protected readonly workspaceService: WorkspaceService;
115
124
 
125
+ @inject(LanguageService)
126
+ protected readonly languageService: LanguageService;
127
+
116
128
  protected readonly onDidChangeEmitter = new Emitter<DidChangeLabelEvent>();
117
129
  readonly onDidChange = this.onDidChangeEmitter.event;
118
130
 
@@ -240,17 +252,18 @@ export class PluginIconTheme extends PluginIconThemeDefinition implements IconTh
240
252
  selectors.push(selector + '::before');
241
253
  definitionSelectors.set(definitionId, selectors);
242
254
  };
243
- this.collectSelectors(json, acceptSelector.bind(undefined, 'dark'));
255
+
256
+ let iconInfo = this.collectSelectors(json, acceptSelector.bind(undefined, 'dark'));
244
257
  if (json.light) {
245
- this.collectSelectors(json.light, acceptSelector.bind(undefined, 'light'));
258
+ iconInfo = this.collectSelectors(json.light, acceptSelector.bind(undefined, 'light'));
246
259
  }
247
260
  if (json.highContrast) {
248
- this.collectSelectors(json.highContrast, acceptSelector.bind(undefined, 'hc'));
261
+ iconInfo = this.collectSelectors(json.highContrast, acceptSelector.bind(undefined, 'hc'));
249
262
  }
250
263
 
251
- if (!this.icons.size) {
252
- return;
253
- }
264
+ const showLanguageModeIcons = this.showLanguageModeIcons === true
265
+ || json.showLanguageModeIcons === true
266
+ || (iconInfo.hasSpecificFileIcons && json.showLanguageModeIcons !== false);
254
267
 
255
268
  const fonts = json.fonts;
256
269
  if (Array.isArray(fonts)) {
@@ -303,7 +316,7 @@ export class PluginIconTheme extends PluginIconThemeDefinition implements IconTh
303
316
  this.styleSheetContent += `${selectors.join(', ')} {
304
317
  content: ' ';
305
318
  background-image: ${cssUrl};
306
- background-size: 16px;
319
+ background-size: ${DEFAULT_ICON_SIZE}px;
307
320
  background-position: left center;
308
321
  background-repeat: no-repeat;
309
322
  }
@@ -327,6 +340,20 @@ export class PluginIconTheme extends PluginIconThemeDefinition implements IconTh
327
340
  }
328
341
  }
329
342
  }
343
+
344
+ if (showLanguageModeIcons) {
345
+ for (const language of this.languageService.languages) {
346
+ // only show language icons if there are no more specific icons in the style document
347
+ if (!iconInfo.coveredLanguages[language.id]) {
348
+ const icon = this.languageService.getIcon(language.id);
349
+ if (icon) {
350
+ this.icons.add(this.fileIcon);
351
+ this.icons.add(this.languageIcon(language.id));
352
+ this.icons.add(icon);
353
+ }
354
+ }
355
+ }
356
+ }
330
357
  }
331
358
 
332
359
  protected toCSSUrl(iconPath: string | undefined): string | undefined {
@@ -348,7 +375,7 @@ export class PluginIconTheme extends PluginIconThemeDefinition implements IconTh
348
375
  return value;
349
376
  }
350
377
 
351
- protected readonly fileIcon = 'theia-plugin-file-icon';
378
+ protected readonly fileIcon = PLUGIN_FILE_ICON_CLASS;
352
379
  protected readonly folderIcon = 'theia-plugin-folder-icon';
353
380
  protected readonly folderExpandedIcon = 'theia-plugin-folder-expanded-icon';
354
381
  protected readonly rootFolderIcon = 'theia-plugin-root-folder-icon';
@@ -384,10 +411,8 @@ export class PluginIconTheme extends PluginIconThemeDefinition implements IconTh
384
411
  return 'theia-plugin-' + this.escapeCSS(languageId) + '-lang-file-icon';
385
412
  }
386
413
 
387
- protected collectSelectors(
388
- associations: RecursivePartial<PluginIconsAssociation>,
389
- accept: (definitionId: string, ...icons: string[]) => void
390
- ): void {
414
+ protected collectSelectors(associations: RecursivePartial<PluginIconsAssociation>, accept: (definitionId: string, ...icons: string[]) => void): PluginLanguageIconInfo {
415
+ const iconInfo = new PluginLanguageIconInfo();
391
416
  if (associations.folder) {
392
417
  accept(associations.folder, this.folderIcon);
393
418
  if (associations.folderExpanded === undefined) {
@@ -441,6 +466,8 @@ export class PluginIconTheme extends PluginIconThemeDefinition implements IconTh
441
466
  for (const languageId in languageIds) {
442
467
  accept(languageIds[languageId]!, this.languageIcon(languageId), this.fileIcon);
443
468
  this.hasFileIcons = true;
469
+ iconInfo.hasSpecificFileIcons = true;
470
+ iconInfo.coveredLanguages[languageId] = true;
444
471
  }
445
472
  }
446
473
  const fileExtensions = associations.fileExtensions;
@@ -449,6 +476,7 @@ export class PluginIconTheme extends PluginIconThemeDefinition implements IconTh
449
476
  for (const fileExtension in fileExtensions) {
450
477
  accept(fileExtensions[fileExtension]!, ...this.fileExtensionIcon(fileExtension), this.fileIcon);
451
478
  this.hasFileIcons = true;
479
+ iconInfo.hasSpecificFileIcons = true;
452
480
  }
453
481
  }
454
482
  const fileNames = associations.fileNames;
@@ -457,8 +485,10 @@ export class PluginIconTheme extends PluginIconThemeDefinition implements IconTh
457
485
  for (const fileName in fileNames) {
458
486
  accept(fileNames[fileName]!, ...this.fileNameIcon(fileName), this.fileIcon);
459
487
  this.hasFileIcons = true;
488
+ iconInfo.hasSpecificFileIcons = true;
460
489
  }
461
490
  }
491
+ return iconInfo;
462
492
  }
463
493
 
464
494
  /**
@@ -529,6 +559,10 @@ export class PluginIconTheme extends PluginIconThemeDefinition implements IconTh
529
559
  }
530
560
  const language = StandaloneServices.get(ILanguageService).createByFilepathOrFirstLine(parsedURI['codeUri']);
531
561
  classNames.push(this.languageIcon(language.languageId));
562
+ const defaultLanguageIcon = this.languageService.getIcon(language.languageId);
563
+ if (defaultLanguageIcon) {
564
+ classNames.push(defaultLanguageIcon);
565
+ }
532
566
  }
533
567
  return classNames;
534
568
  }
@@ -23,14 +23,19 @@ import { Reference, SyncReferenceCollection } from '@theia/core/lib/common/refer
23
23
  import { Endpoint } from '@theia/core/lib/browser/endpoint';
24
24
 
25
25
  export interface PluginIconKey {
26
- url: IconUrl
27
- size: number
26
+ url: IconUrl;
27
+ size?: number;
28
+ type?: 'icon' | 'file';
28
29
  }
29
30
 
30
31
  export interface PluginIcon extends Disposable {
31
32
  readonly iconClass: string
32
33
  }
33
34
 
35
+ export const PLUGIN_FILE_ICON_CLASS = 'theia-plugin-file-icon';
36
+
37
+ export const DEFAULT_ICON_SIZE = 16;
38
+
34
39
  @injectable()
35
40
  export class PluginSharedStyle {
36
41
 
@@ -98,30 +103,45 @@ export class PluginSharedStyle {
98
103
  }
99
104
 
100
105
  private readonly icons = new SyncReferenceCollection<PluginIconKey, PluginIcon>(key => this.createPluginIcon(key));
101
- toIconClass(url: IconUrl, { size }: { size: number } = { size: 16 }): Reference<PluginIcon> {
106
+ toIconClass(url: IconUrl, { size }: { size: number } = { size: DEFAULT_ICON_SIZE }): Reference<PluginIcon> {
102
107
  return this.icons.acquire({ url, size });
103
108
  }
104
109
 
110
+ toFileIconClass(url: IconUrl): Reference<PluginIcon> {
111
+ return this.icons.acquire({ url, type: 'file' });
112
+ }
113
+
105
114
  private iconSequence = 0;
106
115
  protected createPluginIcon(key: PluginIconKey): PluginIcon {
107
116
  const iconUrl = key.url;
108
- const size = key.size;
117
+ const size = key.size ?? DEFAULT_ICON_SIZE;
118
+ const type = key.type ?? 'icon';
109
119
  const darkIconUrl = PluginSharedStyle.toExternalIconUrl(`${typeof iconUrl === 'object' ? iconUrl.dark : iconUrl}`);
110
120
  const lightIconUrl = PluginSharedStyle.toExternalIconUrl(`${typeof iconUrl === 'object' ? iconUrl.light : iconUrl}`);
111
- const iconClass = 'plugin-icon-' + this.iconSequence++;
121
+
112
122
  const toDispose = new DisposableCollection();
113
- toDispose.push(this.insertRule('.' + iconClass + '::before', theme => `
114
- content: "";
115
- background-position: 2px;
116
- width: ${size}px;
117
- height: ${size}px;
118
- background: center no-repeat url("${theme.type === 'light' ? lightIconUrl : darkIconUrl}");
119
- background-size: ${size}px;
120
- `));
121
- return {
122
- iconClass,
123
- dispose: () => toDispose.dispose()
124
- };
123
+ let iconClass = 'plugin-icon-' + this.iconSequence++;
124
+ if (type === 'icon') {
125
+ toDispose.push(this.insertRule('.' + iconClass + '::before', theme => `
126
+ content: "";
127
+ background-position: 2px;
128
+ display: block;
129
+ width: ${size}px;
130
+ height: ${size}px;
131
+ background: center no-repeat url("${theme.type === 'light' ? lightIconUrl : darkIconUrl}");
132
+ background-size: ${size}px;
133
+ `));
134
+ } else {
135
+ toDispose.push(this.insertRule('.' + iconClass + '::before', theme => `
136
+ content: "";
137
+ background-image: url("${theme.type === 'light' ? lightIconUrl : darkIconUrl}");
138
+ background-size: ${DEFAULT_ICON_SIZE}px;
139
+ background-position: left center;
140
+ background-repeat: no-repeat;
141
+ `));
142
+ iconClass += ' ' + PLUGIN_FILE_ICON_CLASS;
143
+ }
144
+ return { iconClass, dispose: () => toDispose.dispose() };
125
145
  }
126
146
 
127
147
  static toExternalIconUrl(iconUrl: string): string {