@theia/plugin-ext 1.70.0-next.7 → 1.70.0-next.71

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 (164) hide show
  1. package/lib/common/plugin-api-rpc-model.d.ts +6 -1
  2. package/lib/common/plugin-api-rpc-model.d.ts.map +1 -1
  3. package/lib/common/plugin-api-rpc-model.js +2 -1
  4. package/lib/common/plugin-api-rpc-model.js.map +1 -1
  5. package/lib/common/plugin-api-rpc.d.ts +25 -2
  6. package/lib/common/plugin-api-rpc.d.ts.map +1 -1
  7. package/lib/common/plugin-api-rpc.js.map +1 -1
  8. package/lib/common/plugin-protocol.d.ts +8 -0
  9. package/lib/common/plugin-protocol.d.ts.map +1 -1
  10. package/lib/common/plugin-protocol.js.map +1 -1
  11. package/lib/hosted/browser/hosted-plugin.d.ts +2 -0
  12. package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
  13. package/lib/hosted/browser/hosted-plugin.js +7 -0
  14. package/lib/hosted/browser/hosted-plugin.js.map +1 -1
  15. package/lib/hosted/common/hosted-plugin.d.ts +3 -0
  16. package/lib/hosted/common/hosted-plugin.d.ts.map +1 -1
  17. package/lib/hosted/common/hosted-plugin.js +13 -0
  18. package/lib/hosted/common/hosted-plugin.js.map +1 -1
  19. package/lib/hosted/common/hosted-plugin.spec.d.ts +2 -0
  20. package/lib/hosted/common/hosted-plugin.spec.d.ts.map +1 -0
  21. package/lib/hosted/common/hosted-plugin.spec.js +308 -0
  22. package/lib/hosted/common/hosted-plugin.spec.js.map +1 -0
  23. package/lib/hosted/node/hosted-plugin-process.d.ts +2 -0
  24. package/lib/hosted/node/hosted-plugin-process.d.ts.map +1 -1
  25. package/lib/hosted/node/hosted-plugin-process.js +8 -0
  26. package/lib/hosted/node/hosted-plugin-process.js.map +1 -1
  27. package/lib/hosted/node/plugin-host-navigator-override.d.ts +12 -0
  28. package/lib/hosted/node/plugin-host-navigator-override.d.ts.map +1 -0
  29. package/lib/hosted/node/plugin-host-navigator-override.js +37 -0
  30. package/lib/hosted/node/plugin-host-navigator-override.js.map +1 -0
  31. package/lib/hosted/node/plugin-host-navigator-override.spec.d.ts +2 -0
  32. package/lib/hosted/node/plugin-host-navigator-override.spec.d.ts.map +1 -0
  33. package/lib/hosted/node/plugin-host-navigator-override.spec.js +49 -0
  34. package/lib/hosted/node/plugin-host-navigator-override.spec.js.map +1 -0
  35. package/lib/hosted/node/plugin-host.js +3 -0
  36. package/lib/hosted/node/plugin-host.js.map +1 -1
  37. package/lib/hosted/node/scanners/scanner-theia.d.ts +1 -0
  38. package/lib/hosted/node/scanners/scanner-theia.d.ts.map +1 -1
  39. package/lib/hosted/node/scanners/scanner-theia.js +7 -0
  40. package/lib/hosted/node/scanners/scanner-theia.js.map +1 -1
  41. package/lib/hosted/node/scanners/scanner-theia.spec.d.ts +2 -0
  42. package/lib/hosted/node/scanners/scanner-theia.spec.d.ts.map +1 -0
  43. package/lib/hosted/node/scanners/scanner-theia.spec.js +93 -0
  44. package/lib/hosted/node/scanners/scanner-theia.spec.js.map +1 -0
  45. package/lib/main/browser/languages-main.d.ts +2 -2
  46. package/lib/main/browser/languages-main.d.ts.map +1 -1
  47. package/lib/main/browser/languages-main.js +14 -10
  48. package/lib/main/browser/languages-main.js.map +1 -1
  49. package/lib/main/browser/menus/menus-contribution-handler.d.ts.map +1 -1
  50. package/lib/main/browser/menus/menus-contribution-handler.js +2 -0
  51. package/lib/main/browser/menus/menus-contribution-handler.js.map +1 -1
  52. package/lib/main/browser/menus/plugin-menu-command-adapter.d.ts.map +1 -1
  53. package/lib/main/browser/menus/plugin-menu-command-adapter.js +3 -0
  54. package/lib/main/browser/menus/plugin-menu-command-adapter.js.map +1 -1
  55. package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts +3 -2
  56. package/lib/main/browser/menus/vscode-theia-menu-mappings.d.ts.map +1 -1
  57. package/lib/main/browser/menus/vscode-theia-menu-mappings.js +10 -2
  58. package/lib/main/browser/menus/vscode-theia-menu-mappings.js.map +1 -1
  59. package/lib/main/browser/plugin-contribution-handler.d.ts.map +1 -1
  60. package/lib/main/browser/plugin-contribution-handler.js +6 -1
  61. package/lib/main/browser/plugin-contribution-handler.js.map +1 -1
  62. package/lib/main/browser/plugin-ext-frontend-module.d.ts.map +1 -1
  63. package/lib/main/browser/plugin-ext-frontend-module.js +26 -0
  64. package/lib/main/browser/plugin-ext-frontend-module.js.map +1 -1
  65. package/lib/main/browser/plugin-ext-widget.d.ts +1 -1
  66. package/lib/main/browser/plugin-ext-widget.d.ts.map +1 -1
  67. package/lib/main/browser/plugin-ext-widget.js +11 -4
  68. package/lib/main/browser/plugin-ext-widget.js.map +1 -1
  69. package/lib/main/browser/scm-main.d.ts +4 -2
  70. package/lib/main/browser/scm-main.d.ts.map +1 -1
  71. package/lib/main/browser/scm-main.js +8 -4
  72. package/lib/main/browser/scm-main.js.map +1 -1
  73. package/lib/main/browser/text-editor-main.d.ts +2 -0
  74. package/lib/main/browser/text-editor-main.d.ts.map +1 -1
  75. package/lib/main/browser/text-editor-main.js +15 -4
  76. package/lib/main/browser/text-editor-main.js.map +1 -1
  77. package/lib/main/browser/text-editors-main.d.ts +4 -0
  78. package/lib/main/browser/text-editors-main.d.ts.map +1 -1
  79. package/lib/main/browser/text-editors-main.js +121 -0
  80. package/lib/main/browser/text-editors-main.js.map +1 -1
  81. package/lib/main/browser/view/plugin-view-registry.d.ts.map +1 -1
  82. package/lib/main/browser/view/plugin-view-registry.js +16 -0
  83. package/lib/main/browser/view/plugin-view-registry.js.map +1 -1
  84. package/lib/main/browser/webview/webview.js +1 -1
  85. package/lib/main/browser/webview/webview.js.map +1 -1
  86. package/lib/main/common/plugin-host-environment-preferences.d.ts +14 -0
  87. package/lib/main/common/plugin-host-environment-preferences.d.ts.map +1 -0
  88. package/lib/main/common/plugin-host-environment-preferences.js +43 -0
  89. package/lib/main/common/plugin-host-environment-preferences.js.map +1 -0
  90. package/lib/main/node/plugin-deployer-impl.d.ts.map +1 -1
  91. package/lib/main/node/plugin-deployer-impl.js +5 -0
  92. package/lib/main/node/plugin-deployer-impl.js.map +1 -1
  93. package/lib/main/node/plugin-ext-backend-module.d.ts.map +1 -1
  94. package/lib/main/node/plugin-ext-backend-module.js +5 -0
  95. package/lib/main/node/plugin-ext-backend-module.js.map +1 -1
  96. package/lib/main/node/plugin-host-navigator-state-initializer.d.ts +17 -0
  97. package/lib/main/node/plugin-host-navigator-state-initializer.d.ts.map +1 -0
  98. package/lib/main/node/plugin-host-navigator-state-initializer.js +53 -0
  99. package/lib/main/node/plugin-host-navigator-state-initializer.js.map +1 -0
  100. package/lib/plugin/command-registry.d.ts.map +1 -1
  101. package/lib/plugin/command-registry.js +11 -0
  102. package/lib/plugin/command-registry.js.map +1 -1
  103. package/lib/plugin/env.d.ts +5 -0
  104. package/lib/plugin/env.d.ts.map +1 -1
  105. package/lib/plugin/env.js +7 -0
  106. package/lib/plugin/env.js.map +1 -1
  107. package/lib/plugin/file-system-event-service-ext-impl.d.ts +1 -1
  108. package/lib/plugin/file-system-event-service-ext-impl.d.ts.map +1 -1
  109. package/lib/plugin/file-system-ext-impl.d.ts +1 -1
  110. package/lib/plugin/file-system-ext-impl.d.ts.map +1 -1
  111. package/lib/plugin/file-system-ext-impl.js +5 -1
  112. package/lib/plugin/file-system-ext-impl.js.map +1 -1
  113. package/lib/plugin/plugin-context.d.ts.map +1 -1
  114. package/lib/plugin/plugin-context.js +3 -2
  115. package/lib/plugin/plugin-context.js.map +1 -1
  116. package/lib/plugin/scm.d.ts +2 -1
  117. package/lib/plugin/scm.d.ts.map +1 -1
  118. package/lib/plugin/scm.js +20 -3
  119. package/lib/plugin/scm.js.map +1 -1
  120. package/lib/plugin/text-editors.d.ts +2 -2
  121. package/lib/plugin/text-editors.d.ts.map +1 -1
  122. package/lib/plugin/text-editors.js.map +1 -1
  123. package/lib/plugin/types-impl.d.ts +2 -1
  124. package/lib/plugin/types-impl.d.ts.map +1 -1
  125. package/lib/plugin/types-impl.js.map +1 -1
  126. package/package.json +30 -30
  127. package/src/common/plugin-api-rpc-model.ts +10 -1
  128. package/src/common/plugin-api-rpc.ts +21 -2
  129. package/src/common/plugin-protocol.ts +9 -1
  130. package/src/hosted/browser/hosted-plugin.ts +6 -0
  131. package/src/hosted/common/hosted-plugin.spec.ts +377 -0
  132. package/src/hosted/common/hosted-plugin.ts +18 -1
  133. package/src/hosted/node/hosted-plugin-process.ts +7 -0
  134. package/src/hosted/node/plugin-host-navigator-override.spec.ts +53 -0
  135. package/src/hosted/node/plugin-host-navigator-override.ts +34 -0
  136. package/src/hosted/node/plugin-host.ts +4 -0
  137. package/src/hosted/node/scanners/scanner-theia.spec.ts +112 -0
  138. package/src/hosted/node/scanners/scanner-theia.ts +8 -0
  139. package/src/main/browser/languages-main.ts +38 -52
  140. package/src/main/browser/menus/menus-contribution-handler.ts +2 -0
  141. package/src/main/browser/menus/plugin-menu-command-adapter.ts +3 -0
  142. package/src/main/browser/menus/vscode-theia-menu-mappings.ts +12 -2
  143. package/src/main/browser/plugin-contribution-handler.ts +6 -1
  144. package/src/main/browser/plugin-ext-frontend-module.ts +31 -1
  145. package/src/main/browser/plugin-ext-widget.tsx +14 -4
  146. package/src/main/browser/scm-main.ts +13 -6
  147. package/src/main/browser/style/plugin-sidebar.css +13 -0
  148. package/src/main/browser/text-editor-main.ts +14 -2
  149. package/src/main/browser/text-editors-main.ts +132 -0
  150. package/src/main/browser/view/plugin-view-registry.ts +18 -1
  151. package/src/main/browser/webview/pre/main.js +9 -9
  152. package/src/main/browser/webview/webview.ts +1 -1
  153. package/src/main/common/plugin-host-environment-preferences.ts +48 -0
  154. package/src/main/node/plugin-deployer-impl.ts +5 -0
  155. package/src/main/node/plugin-ext-backend-module.ts +5 -1
  156. package/src/main/node/plugin-host-navigator-state-initializer.ts +47 -0
  157. package/src/plugin/command-registry.ts +12 -1
  158. package/src/plugin/env.ts +8 -0
  159. package/src/plugin/file-system-event-service-ext-impl.ts +1 -1
  160. package/src/plugin/file-system-ext-impl.ts +1 -2
  161. package/src/plugin/plugin-context.ts +3 -2
  162. package/src/plugin/scm.ts +26 -4
  163. package/src/plugin/text-editors.ts +2 -2
  164. package/src/plugin/types-impl.ts +2 -1
@@ -0,0 +1,112 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2026 EclipseSource and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ /* eslint-disable @typescript-eslint/no-explicit-any */
18
+
19
+ import { expect } from 'chai';
20
+ import * as os from 'os';
21
+ import * as path from 'path';
22
+ import * as fs from 'fs';
23
+ import { AbstractPluginScanner } from './scanner-theia';
24
+ import { PluginPackage, PluginEntryPoint } from '../../../common/plugin-protocol';
25
+ import URI from '@theia/core/lib/common/uri';
26
+
27
+ class TestPluginScanner extends AbstractPluginScanner {
28
+ constructor() {
29
+ // Use a dummy api type; no backend init path needed
30
+ super('theiaPlugin' as any);
31
+ }
32
+
33
+ protected getEntryPoint(_plugin: PluginPackage): PluginEntryPoint {
34
+ return { backend: 'main.js' };
35
+ }
36
+ }
37
+
38
+ function createMinimalPluginPackage(
39
+ capabilities?: PluginPackage['capabilities'],
40
+ packagePath?: string
41
+ ): PluginPackage {
42
+ return {
43
+ name: 'test-plugin',
44
+ publisher: 'test-publisher',
45
+ version: '1.0.0',
46
+ engines: { theiaPlugin: '1.0.0' },
47
+ displayName: 'Test Plugin',
48
+ description: 'A test plugin',
49
+ packagePath: packagePath ?? os.tmpdir(),
50
+ capabilities
51
+ } as PluginPackage;
52
+ }
53
+
54
+ describe('AbstractPluginScanner', () => {
55
+ let scanner: TestPluginScanner;
56
+ let tmpDir: string;
57
+
58
+ before(() => {
59
+ scanner = new TestPluginScanner();
60
+ // Inject a mock pluginUriFactory
61
+ (scanner as any).pluginUriFactory = {
62
+ createUri: (_pkg: PluginPackage, _relativePath?: string) => new URI('file:///dummy')
63
+ };
64
+ // Create a real temp directory so readdirSync in getLicenseUrl/getReadmeUrl works
65
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'scanner-test-'));
66
+ });
67
+
68
+ after(() => {
69
+ fs.rmSync(tmpDir, { recursive: true, force: true });
70
+ });
71
+
72
+ it('should set untrustedWorkspacesSupport to false when capabilities.untrustedWorkspaces.supported is false', () => {
73
+ const pkg = createMinimalPluginPackage({
74
+ untrustedWorkspaces: { supported: false }
75
+ }, tmpDir);
76
+
77
+ const model = scanner.getModel(pkg);
78
+ expect(model.untrustedWorkspacesSupport).to.equal(false);
79
+ });
80
+
81
+ it('should set untrustedWorkspacesSupport to true when capabilities.untrustedWorkspaces.supported is true', () => {
82
+ const pkg = createMinimalPluginPackage({
83
+ untrustedWorkspaces: { supported: true }
84
+ }, tmpDir);
85
+
86
+ const model = scanner.getModel(pkg);
87
+ expect(model.untrustedWorkspacesSupport).to.equal(true);
88
+ });
89
+
90
+ it('should set untrustedWorkspacesSupport to "limited" when capabilities.untrustedWorkspaces.supported is "limited"', () => {
91
+ const pkg = createMinimalPluginPackage({
92
+ untrustedWorkspaces: { supported: 'limited' }
93
+ }, tmpDir);
94
+
95
+ const model = scanner.getModel(pkg);
96
+ expect(model.untrustedWorkspacesSupport).to.equal('limited');
97
+ });
98
+
99
+ it('should leave untrustedWorkspacesSupport undefined when no capabilities field is present', () => {
100
+ const pkg = createMinimalPluginPackage(undefined, tmpDir);
101
+
102
+ const model = scanner.getModel(pkg);
103
+ expect(model.untrustedWorkspacesSupport).to.equal(undefined);
104
+ });
105
+
106
+ it('should leave untrustedWorkspacesSupport undefined when capabilities has no untrustedWorkspaces', () => {
107
+ const pkg = createMinimalPluginPackage({} as any, tmpDir);
108
+
109
+ const model = scanner.getModel(pkg);
110
+ expect(model.untrustedWorkspacesSupport).to.equal(undefined);
111
+ });
112
+ });
@@ -177,9 +177,17 @@ export abstract class AbstractPluginScanner implements PluginScanner {
177
177
  licenseUrl: this.getLicenseUrl(plugin),
178
178
  readmeUrl: this.getReadmeUrl(plugin)
179
179
  };
180
+ this.applyTrustExtraction(plugin, result);
180
181
  return result;
181
182
  }
182
183
 
184
+ protected applyTrustExtraction(plugin: PluginPackage, result: PluginModel): void {
185
+ const untrustedWorkspacesSupport = plugin.capabilities?.untrustedWorkspaces?.supported;
186
+ if (untrustedWorkspacesSupport !== undefined) {
187
+ result.untrustedWorkspacesSupport = untrustedWorkspacesSupport;
188
+ }
189
+ }
190
+
183
191
  protected getReadmeUrl(plugin: PluginPackage): string | undefined {
184
192
  return this.getPluginRootFileUrl(plugin, ['readme.md', 'readme.txt', 'readme']);
185
193
  }
@@ -87,15 +87,6 @@ import { CodeActionTriggerKind } from '../../plugin/types-impl';
87
87
  import { IReadonlyVSDataTransfer } from '@theia/monaco-editor-core/esm/vs/base/common/dataTransfer';
88
88
  import { FileUploadService } from '@theia/filesystem/lib/common/upload/file-upload';
89
89
 
90
- /**
91
- * @monaco-uplift The public API declares these functions as (languageId: string, service).
92
- * Confirm that the functions delegate to a handler that accepts a LanguageSelector rather than just a string.
93
- * Relevant code in node_modules/@theia/monaco-editor-core/src/vs/editor/standalone/browser/standaloneLanguages.ts
94
- */
95
- interface RegistrationFunction<T> {
96
- (languageId: MonacoLanguageSelector.LanguageSelector, service: T): Disposable;
97
- }
98
-
99
90
  @injectable()
100
91
  export class LanguagesMainImpl implements LanguagesMain, Disposable {
101
92
 
@@ -161,8 +152,13 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
161
152
  }
162
153
 
163
154
  $setLanguageConfiguration(handle: number, languageId: string, configuration: SerializedLanguageConfiguration): void {
155
+ const comments = configuration.comments;
164
156
  const config: monaco.languages.LanguageConfiguration = {
165
- comments: configuration.comments,
157
+ comments: comments ? {
158
+ // @monaco-uplift: Monaco doesn't support LineCommentRule yet, extract the string
159
+ lineComment: comments.lineComment && typeof comments.lineComment === 'object' ? comments.lineComment.comment : comments.lineComment,
160
+ blockComment: comments.blockComment,
161
+ } : undefined,
166
162
  brackets: configuration.brackets,
167
163
  wordPattern: reviveRegExp(configuration.wordPattern),
168
164
  indentationRules: reviveIndentationRule(configuration.indentationRules),
@@ -175,7 +171,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
175
171
 
176
172
  $registerCompletionSupport(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[], triggerCharacters: string[], supportsResolveDetails: boolean): void {
177
173
  this.register(handle,
178
- (monaco.languages.registerCompletionItemProvider as RegistrationFunction<monaco.languages.CompletionItemProvider>)(this.toLanguageSelector(selector), {
174
+ monaco.languages.registerCompletionItemProvider(this.toLanguageSelector(selector), {
179
175
  triggerCharacters,
180
176
  provideCompletionItems: (model, position, context, token) => this.provideCompletionItems(handle, model, position, context, token),
181
177
  resolveCompletionItem: supportsResolveDetails
@@ -214,19 +210,19 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
214
210
  $registerDefinitionProvider(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[]): void {
215
211
  const languageSelector = this.toLanguageSelector(selector);
216
212
  const definitionProvider = this.createDefinitionProvider(handle);
217
- this.register(handle, (monaco.languages.registerDefinitionProvider as RegistrationFunction<monaco.languages.DefinitionProvider>)(languageSelector, definitionProvider));
213
+ this.register(handle, monaco.languages.registerDefinitionProvider(languageSelector, definitionProvider));
218
214
  }
219
215
 
220
216
  $registerDeclarationProvider(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[]): void {
221
217
  const languageSelector = this.toLanguageSelector(selector);
222
218
  const declarationProvider = this.createDeclarationProvider(handle);
223
- this.register(handle, (monaco.languages.registerDeclarationProvider as RegistrationFunction<monaco.languages.DeclarationProvider>)(languageSelector, declarationProvider));
219
+ this.register(handle, monaco.languages.registerDeclarationProvider(languageSelector, declarationProvider));
224
220
  }
225
221
 
226
222
  $registerReferenceProvider(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[]): void {
227
223
  const languageSelector = this.toLanguageSelector(selector);
228
224
  const referenceProvider = this.createReferenceProvider(handle);
229
- this.register(handle, (monaco.languages.registerReferenceProvider as RegistrationFunction<monaco.languages.ReferenceProvider>)(languageSelector, referenceProvider));
225
+ this.register(handle, monaco.languages.registerReferenceProvider(languageSelector, referenceProvider));
230
226
  }
231
227
 
232
228
  protected createReferenceProvider(handle: number): monaco.languages.ReferenceProvider {
@@ -257,8 +253,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
257
253
  $registerSignatureHelpProvider(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[], metadata: theia.SignatureHelpProviderMetadata): void {
258
254
  const languageSelector = this.toLanguageSelector(selector);
259
255
  const signatureHelpProvider = this.createSignatureHelpProvider(handle, metadata);
260
- this.register(handle, (monaco.languages.registerSignatureHelpProvider as RegistrationFunction<monaco.languages.SignatureHelpProvider>)
261
- (languageSelector, signatureHelpProvider));
256
+ this.register(handle, monaco.languages.registerSignatureHelpProvider(languageSelector, signatureHelpProvider));
262
257
  }
263
258
 
264
259
  $clearDiagnostics(id: string): void {
@@ -277,8 +272,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
277
272
  $registerImplementationProvider(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[]): void {
278
273
  const languageSelector = this.toLanguageSelector(selector);
279
274
  const implementationProvider = this.createImplementationProvider(handle);
280
- this.register(handle, (monaco.languages.registerImplementationProvider as RegistrationFunction<monaco.languages.ImplementationProvider>)
281
- (languageSelector, implementationProvider));
275
+ this.register(handle, monaco.languages.registerImplementationProvider(languageSelector, implementationProvider));
282
276
  }
283
277
 
284
278
  protected createImplementationProvider(handle: number): monaco.languages.ImplementationProvider {
@@ -314,8 +308,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
314
308
  $registerTypeDefinitionProvider(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[]): void {
315
309
  const languageSelector = this.toLanguageSelector(selector);
316
310
  const typeDefinitionProvider = this.createTypeDefinitionProvider(handle);
317
- this.register(handle, (monaco.languages.registerTypeDefinitionProvider as RegistrationFunction<monaco.languages.TypeDefinitionProvider>)
318
- (languageSelector, typeDefinitionProvider));
311
+ this.register(handle, monaco.languages.registerTypeDefinitionProvider(languageSelector, typeDefinitionProvider));
319
312
  }
320
313
 
321
314
  protected createTypeDefinitionProvider(handle: number): monaco.languages.TypeDefinitionProvider {
@@ -351,7 +344,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
351
344
  $registerHoverProvider(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[]): void {
352
345
  const languageSelector = this.toLanguageSelector(selector);
353
346
  const hoverProvider = this.createHoverProvider(handle);
354
- this.register(handle, (monaco.languages.registerHoverProvider as RegistrationFunction<monaco.languages.HoverProvider>)(languageSelector, hoverProvider));
347
+ this.register(handle, monaco.languages.registerHoverProvider(languageSelector, hoverProvider));
355
348
  }
356
349
 
357
350
  protected createHoverProvider(handle: number): monaco.languages.HoverProvider {
@@ -375,7 +368,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
375
368
  const languageSelector = this.toLanguageSelector(selector);
376
369
  const evaluatableExpressionProvider = this.createEvaluatableExpressionProvider(handle);
377
370
  this.register(handle,
378
- (StandaloneServices.get(ILanguageFeaturesService).evaluatableExpressionProvider.register as RegistrationFunction<EvaluatableExpressionProvider>)
371
+ (StandaloneServices.get(ILanguageFeaturesService).evaluatableExpressionProvider.register)
379
372
  (languageSelector, evaluatableExpressionProvider));
380
373
  }
381
374
 
@@ -394,7 +387,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
394
387
  const languageSelector = this.toLanguageSelector(selector);
395
388
  const inlineValuesProvider = this.createInlineValuesProvider(handle);
396
389
  this.register(handle,
397
- (StandaloneServices.get(ILanguageFeaturesService).inlineValuesProvider.register as RegistrationFunction<InlineValuesProvider>)
390
+ (StandaloneServices.get(ILanguageFeaturesService).inlineValuesProvider.register)
398
391
  (languageSelector, inlineValuesProvider));
399
392
  }
400
393
 
@@ -420,8 +413,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
420
413
  $registerDocumentHighlightProvider(handle: number, _pluginInfo: PluginInfo, selector: SerializedDocumentFilter[]): void {
421
414
  const languageSelector = this.toLanguageSelector(selector);
422
415
  const documentHighlightProvider = this.createDocumentHighlightProvider(handle);
423
- this.register(handle, (monaco.languages.registerDocumentHighlightProvider as RegistrationFunction<monaco.languages.DocumentHighlightProvider>)
424
- (languageSelector, documentHighlightProvider));
416
+ this.register(handle, monaco.languages.registerDocumentHighlightProvider(languageSelector, documentHighlightProvider));
425
417
  }
426
418
 
427
419
  protected createDocumentHighlightProvider(handle: number): monaco.languages.DocumentHighlightProvider {
@@ -476,7 +468,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
476
468
  $registerDocumentLinkProvider(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[]): void {
477
469
  const languageSelector = this.toLanguageSelector(selector);
478
470
  const linkProvider = this.createLinkProvider(handle);
479
- this.register(handle, (monaco.languages.registerLinkProvider as RegistrationFunction<monaco.languages.LinkProvider>)(languageSelector, linkProvider));
471
+ this.register(handle, monaco.languages.registerLinkProvider(languageSelector, linkProvider));
480
472
  }
481
473
 
482
474
  protected createLinkProvider(handle: number): monaco.languages.LinkProvider {
@@ -525,7 +517,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
525
517
  lensProvider.onDidChange = emitter.event;
526
518
  }
527
519
 
528
- this.register(handle, (monaco.languages.registerCodeLensProvider as RegistrationFunction<monaco.languages.CodeLensProvider>)(languageSelector, lensProvider));
520
+ this.register(handle, monaco.languages.registerCodeLensProvider(languageSelector, lensProvider));
529
521
  }
530
522
 
531
523
  protected createCodeLensProvider(handle: number): monaco.languages.CodeLensProvider {
@@ -567,7 +559,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
567
559
  $registerOutlineSupport(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[], displayName?: string): void {
568
560
  const languageSelector = this.toLanguageSelector(selector);
569
561
  const symbolProvider = this.createDocumentSymbolProvider(handle, displayName);
570
- this.register(handle, (monaco.languages.registerDocumentSymbolProvider as RegistrationFunction<monaco.languages.DocumentSymbolProvider>)(languageSelector, symbolProvider));
562
+ this.register(handle, monaco.languages.registerDocumentSymbolProvider(languageSelector, symbolProvider));
571
563
  }
572
564
 
573
565
  protected createDocumentSymbolProvider(handle: number, displayName?: string): monaco.languages.DocumentSymbolProvider {
@@ -672,8 +664,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
672
664
  $registerDocumentFormattingSupport(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[]): void {
673
665
  const languageSelector = this.toLanguageSelector(selector);
674
666
  const documentFormattingEditSupport = this.createDocumentFormattingSupport(handle, pluginInfo);
675
- this.register(handle, (monaco.languages.registerDocumentFormattingEditProvider as RegistrationFunction<monaco.languages.DocumentFormattingEditProvider>)
676
- (languageSelector, documentFormattingEditSupport));
667
+ this.register(handle, monaco.languages.registerDocumentFormattingEditProvider(languageSelector, documentFormattingEditSupport));
677
668
  }
678
669
 
679
670
  createDocumentFormattingSupport(handle: number, pluginInfo: PluginInfo): monaco.languages.DocumentFormattingEditProvider {
@@ -695,8 +686,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
695
686
  $registerRangeFormattingSupport(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[]): void {
696
687
  const languageSelector = this.toLanguageSelector(selector);
697
688
  const rangeFormattingEditProvider = this.createRangeFormattingSupport(handle, pluginInfo);
698
- this.register(handle, (monaco.languages.registerDocumentRangeFormattingEditProvider as RegistrationFunction<monaco.languages.DocumentRangeFormattingEditProvider>)
699
- (languageSelector, rangeFormattingEditProvider));
689
+ this.register(handle, monaco.languages.registerDocumentRangeFormattingEditProvider(languageSelector, rangeFormattingEditProvider));
700
690
  }
701
691
 
702
692
  createRangeFormattingSupport(handle: number, pluginInfo: PluginInfo): monaco.languages.DocumentRangeFormattingEditProvider {
@@ -718,8 +708,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
718
708
  $registerOnTypeFormattingProvider(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[], autoFormatTriggerCharacters: string[]): void {
719
709
  const languageSelector = this.toLanguageSelector(selector);
720
710
  const onTypeFormattingProvider = this.createOnTypeFormattingProvider(handle, autoFormatTriggerCharacters);
721
- this.register(handle, (monaco.languages.registerOnTypeFormattingEditProvider as RegistrationFunction<monaco.languages.OnTypeFormattingEditProvider>)
722
- (languageSelector, onTypeFormattingProvider));
711
+ this.register(handle, monaco.languages.registerOnTypeFormattingEditProvider(languageSelector, onTypeFormattingProvider));
723
712
  }
724
713
 
725
714
  protected createOnTypeFormattingProvider(
@@ -747,11 +736,9 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
747
736
  );
748
737
  }
749
738
 
750
- createDocumentDropEditProvider(handle: number, _metadata?: DocumentDropEditProviderMetadata): DocumentDropEditProvider {
739
+ createDocumentDropEditProvider(handle: number, metadata?: DocumentDropEditProviderMetadata): DocumentDropEditProvider {
751
740
  return {
752
- // @monaco-uplift id and dropMimeTypes should be supported by the monaco drop editor provider after 1.82.0
753
- // id?: string;
754
- // dropMimeTypes: metadata?.dropMimeTypes ?? ['*/*'],
741
+ dropMimeTypes: metadata?.dropMimeTypes ?? ['*/*'],
755
742
  provideDocumentDropEdits: async (model, position, dataTransfer, token) => this.provideDocumentDropEdits(handle, model, position, dataTransfer, token)
756
743
  };
757
744
  }
@@ -772,7 +759,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
772
759
  provider.onDidChange = emitter.event;
773
760
  }
774
761
 
775
- this.register(handle, (monaco.languages.registerFoldingRangeProvider as RegistrationFunction<monaco.languages.FoldingRangeProvider>)(languageSelector, provider));
762
+ this.register(handle, monaco.languages.registerFoldingRangeProvider(languageSelector, provider));
776
763
  }
777
764
 
778
765
  createFoldingRangeProvider(handle: number): monaco.languages.FoldingRangeProvider {
@@ -796,7 +783,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
796
783
  $registerSelectionRangeProvider(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[]): void {
797
784
  const languageSelector = this.toLanguageSelector(selector);
798
785
  const provider = this.createSelectionRangeProvider(handle);
799
- this.register(handle, (monaco.languages.registerSelectionRangeProvider as RegistrationFunction<monaco.languages.SelectionRangeProvider>)(languageSelector, provider));
786
+ this.register(handle, monaco.languages.registerSelectionRangeProvider(languageSelector, provider));
800
787
  }
801
788
 
802
789
  protected createSelectionRangeProvider(handle: number): monaco.languages.SelectionRangeProvider {
@@ -813,7 +800,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
813
800
  $registerDocumentColorProvider(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[]): void {
814
801
  const languageSelector = this.toLanguageSelector(selector);
815
802
  const colorProvider = this.createColorProvider(handle);
816
- this.register(handle, (monaco.languages.registerColorProvider as RegistrationFunction<monaco.languages.DocumentColorProvider>)(languageSelector, colorProvider));
803
+ this.register(handle, monaco.languages.registerColorProvider(languageSelector, colorProvider));
817
804
  }
818
805
 
819
806
  createColorProvider(handle: number): monaco.languages.DocumentColorProvider {
@@ -864,7 +851,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
864
851
  this.register(eventHandle, emitter);
865
852
  inlayHintsProvider.onDidChangeInlayHints = emitter.event;
866
853
  }
867
- this.register(handle, (monaco.languages.registerInlayHintsProvider as RegistrationFunction<monaco.languages.InlayHintsProvider>)(languageSelector, inlayHintsProvider));
854
+ this.register(handle, monaco.languages.registerInlayHintsProvider(languageSelector, inlayHintsProvider));
868
855
 
869
856
  }
870
857
 
@@ -923,11 +910,11 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
923
910
  context: monaco.languages.InlineCompletionContext,
924
911
  token: CancellationToken
925
912
  ): Promise<IdentifiableInlineCompletions | undefined> => this.proxy.$provideInlineCompletions(handle, model.uri, position, context, token),
926
- freeInlineCompletions: (completions: IdentifiableInlineCompletions): void => {
913
+ disposeInlineCompletions: (completions: IdentifiableInlineCompletions): void => {
927
914
  this.proxy.$freeInlineCompletionsList(handle, completions.pid);
928
915
  }
929
916
  };
930
- this.register(handle, (monaco.languages.registerInlineCompletionsProvider as RegistrationFunction<monaco.languages.InlineCompletionsProvider>)(languageSelector, provider));
917
+ this.register(handle, monaco.languages.registerInlineCompletionsProvider(languageSelector, provider));
931
918
  }
932
919
 
933
920
  $registerQuickFixProvider(
@@ -1005,7 +992,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
1005
992
  $registerRenameProvider(handle: number, pluginInfo: PluginInfo, selector: SerializedDocumentFilter[], supportsResolveLocation: boolean): void {
1006
993
  const languageSelector = this.toLanguageSelector(selector);
1007
994
  const renameProvider = this.createRenameProvider(handle, supportsResolveLocation);
1008
- this.register(handle, (monaco.languages.registerRenameProvider as RegistrationFunction<monaco.languages.RenameProvider>)(languageSelector, renameProvider));
995
+ this.register(handle, monaco.languages.registerRenameProvider(languageSelector, renameProvider));
1009
996
  }
1010
997
 
1011
998
  protected createRenameProvider(handle: number, supportsResolveLocation: boolean): monaco.languages.RenameProvider {
@@ -1140,12 +1127,12 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
1140
1127
  event = emitter.event;
1141
1128
  }
1142
1129
  const provider = this.createDocumentSemanticTokensProvider(handle, legend, event);
1143
- this.register(handle, (monaco.languages.registerDocumentSemanticTokensProvider as RegistrationFunction<monaco.languages.DocumentSemanticTokensProvider>)
1144
- (languageSelector, provider));
1130
+ this.register(handle, monaco.languages.registerDocumentSemanticTokensProvider(languageSelector, provider));
1145
1131
  }
1146
1132
 
1147
1133
  protected createDocumentSemanticTokensProvider(handle: number, legend: theia.SemanticTokensLegend, event?: Event<void>): monaco.languages.DocumentSemanticTokensProvider {
1148
1134
  return {
1135
+ onDidChange: event,
1149
1136
  releaseDocumentSemanticTokens: resultId => {
1150
1137
  if (resultId) {
1151
1138
  this.proxy.$releaseDocumentSemanticTokens(handle, parseInt(resultId, 10));
@@ -1193,14 +1180,14 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
1193
1180
  event = emitter.event;
1194
1181
  }
1195
1182
  const provider = this.createDocumentRangeSemanticTokensProvider(handle, legend, event);
1196
- this.register(handle, (monaco.languages.registerDocumentRangeSemanticTokensProvider as RegistrationFunction<monaco.languages.DocumentRangeSemanticTokensProvider>)
1197
- (languageSelector, provider));
1183
+ this.register(handle, monaco.languages.registerDocumentRangeSemanticTokensProvider(languageSelector, provider));
1198
1184
  }
1199
1185
 
1200
1186
  protected createDocumentRangeSemanticTokensProvider(
1201
- handle: number, legend: theia.SemanticTokensLegend, _onDidChangeEvent?: Event<void>
1187
+ handle: number, legend: theia.SemanticTokensLegend, event?: Event<void>
1202
1188
  ): monaco.languages.DocumentRangeSemanticTokensProvider {
1203
1189
  return {
1190
+ onDidChange: event,
1204
1191
  getLegend: () => legend,
1205
1192
  provideDocumentRangeSemanticTokens: async (model, range, token) => {
1206
1193
  const encodedDto = await this.proxy.$provideDocumentRangeSemanticTokens(handle, model.uri, range, token);
@@ -1219,7 +1206,6 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
1219
1206
  }
1220
1207
  throw new Error('Unexpected');
1221
1208
  },
1222
- // @monaco-uplift onDidChange property is not yet available with the current monaco version, probably with the next monaco update then
1223
1209
  };
1224
1210
  }
1225
1211
 
@@ -1251,7 +1237,7 @@ export class LanguagesMainImpl implements LanguagesMain, Disposable {
1251
1237
  const languageSelector = this.toLanguageSelector(selector);
1252
1238
  const linkedEditingRangeProvider = this.createLinkedEditingRangeProvider(handle);
1253
1239
  this.register(handle,
1254
- (monaco.languages.registerLinkedEditingRangeProvider as RegistrationFunction<monaco.languages.LinkedEditingRangeProvider>)(languageSelector, linkedEditingRangeProvider)
1240
+ monaco.languages.registerLinkedEditingRangeProvider(languageSelector, linkedEditingRangeProvider)
1255
1241
  );
1256
1242
  }
1257
1243
 
@@ -22,6 +22,7 @@ import { MenuModelRegistry } from '@theia/core/lib/common';
22
22
  import { TabBarToolbarRegistry } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
23
23
  import { DeployedPlugin, IconUrl, Menu } from '../../../common';
24
24
  import { ScmWidget } from '@theia/scm/lib/browser/scm-widget';
25
+ import { ScmRepositoriesWidget, SCM_SOURCE_CONTROL_TITLE_MENU } from '@theia/scm/lib/browser/scm-repositories-widget';
25
26
  import { KeybindingRegistry, QuickCommandService, codicon } from '@theia/core/lib/browser';
26
27
  import {
27
28
  CodeEditorWidgetUtil, codeToTheiaMappings, ContributionPoint,
@@ -61,6 +62,7 @@ export class MenusContributionPointHandler {
61
62
  isVisible: widget => CodeEditorWidgetUtil.is(widget)
62
63
  });
63
64
  this.tabBarToolbar.registerMenuDelegate(PLUGIN_SCM_TITLE_MENU, widget => widget instanceof ScmWidget);
65
+ this.tabBarToolbar.registerMenuDelegate(SCM_SOURCE_CONTROL_TITLE_MENU, widget => widget instanceof ScmRepositoriesWidget);
64
66
  this.tabBarToolbar.registerMenuDelegate(PLUGIN_VIEW_TITLE_MENU, widget => !CodeEditorWidgetUtil.is(widget));
65
67
  }
66
68
 
@@ -70,6 +70,9 @@ export class PluginMenuCommandAdapter {
70
70
  ['scm/resourceGroup/context', toScmArgs],
71
71
  ['scm/resourceState/context', toScmArgs],
72
72
  ['scm/title', () => [this.toScmArg(this.scmService.selectedRepository)]],
73
+ ['scm/sourceControl', toScmArgs],
74
+ ['scm/sourceControl/context', toScmArgs],
75
+ ['scm/sourceControl/title', () => [this.toScmArg(this.scmService.selectedRepository)]],
73
76
  ['testing/message/context', toTestMessageArgs],
74
77
  ['testing/profiles/context', noArgs],
75
78
  ['scm/change/title', (...args) => this.toScmChangeArgs(...args)],
@@ -26,6 +26,9 @@ import { EditorWidget, EDITOR_CONTEXT_MENU, EDITOR_CONTENT_MENU } from '@theia/e
26
26
  import { NAVIGATOR_CONTEXT_MENU } from '@theia/navigator/lib/browser/navigator-contribution';
27
27
  import { ScmTreeWidget } from '@theia/scm/lib/browser/scm-tree-widget';
28
28
  import { PLUGIN_SCM_CHANGE_TITLE_MENU } from '@theia/scm/lib/browser/dirty-diff/dirty-diff-widget';
29
+ import {
30
+ SCM_SOURCE_CONTROL_CONTEXT_MENU, SCM_SOURCE_CONTROL_MENU, SCM_SOURCE_CONTROL_TITLE_MENU, SCM_TITLE_MENU
31
+ } from '@theia/scm/lib/browser/scm-repositories-widget';
29
32
  import { TIMELINE_ITEM_CONTEXT_MENU } from '@theia/timeline/lib/browser/timeline-tree-widget';
30
33
  import { COMMENT_CONTEXT, COMMENT_THREAD_CONTEXT, COMMENT_TITLE } from '../comments/comment-thread-widget';
31
34
  import { VIEW_ITEM_CONTEXT_MENU } from '../view/tree-view-widget';
@@ -37,7 +40,8 @@ import { TerminalMenus } from '@theia/terminal/lib/browser/terminal-frontend-con
37
40
 
38
41
  export const PLUGIN_EDITOR_TITLE_MENU = ['plugin_editor/title'];
39
42
  export const PLUGIN_EDITOR_TITLE_RUN_MENU = ['plugin_editor/title/run'];
40
- export const PLUGIN_SCM_TITLE_MENU = ['plugin_scm/title'];
43
+ /** @deprecated Use SCM_TITLE_MENU from @theia/scm/lib/browser/scm-repositories-widget */
44
+ export const PLUGIN_SCM_TITLE_MENU = SCM_TITLE_MENU;
41
45
  export const PLUGIN_VIEW_TITLE_MENU = ['plugin_view/title'];
42
46
 
43
47
  export const implementedVSCodeContributionPoints = [
@@ -58,6 +62,9 @@ export const implementedVSCodeContributionPoints = [
58
62
  'scm/resourceFolder/context',
59
63
  'scm/resourceGroup/context',
60
64
  'scm/resourceState/context',
65
+ 'scm/sourceControl',
66
+ 'scm/sourceControl/context',
67
+ 'scm/sourceControl/title',
61
68
  'scm/title',
62
69
  'timeline/item/context',
63
70
  'testing/item/context',
@@ -93,7 +100,10 @@ export const codeToTheiaMappings = new Map<string, MenuPath[]>([
93
100
  ['scm/resourceFolder/context', [ScmTreeWidget.RESOURCE_FOLDER_CONTEXT_MENU]],
94
101
  ['scm/resourceGroup/context', [ScmTreeWidget.RESOURCE_GROUP_CONTEXT_MENU]],
95
102
  ['scm/resourceState/context', [ScmTreeWidget.RESOURCE_CONTEXT_MENU]],
96
- ['scm/title', [PLUGIN_SCM_TITLE_MENU]],
103
+ ['scm/sourceControl', [SCM_SOURCE_CONTROL_MENU]],
104
+ ['scm/sourceControl/context', [SCM_SOURCE_CONTROL_CONTEXT_MENU]],
105
+ ['scm/sourceControl/title', [SCM_SOURCE_CONTROL_TITLE_MENU]],
106
+ ['scm/title', [SCM_TITLE_MENU]],
97
107
  ['testing/item/context', [TEST_VIEW_CONTEXT_MENU]],
98
108
  ['testing/message/context', [TEST_RUNS_CONTEXT_MENU]],
99
109
  ['testing/profiles/context', [PLUGIN_TEST_VIEW_TITLE_MENU]],
@@ -209,11 +209,16 @@ export class PluginContributionHandler {
209
209
  }
210
210
  const langConfiguration = lang.configuration;
211
211
  if (langConfiguration) {
212
+ const comments = langConfiguration.comments;
212
213
  pushContribution(`language.${lang.id}.configuration`, () => monaco.languages.setLanguageConfiguration(lang.id, {
213
214
  wordPattern: this.createRegex(langConfiguration.wordPattern),
214
215
  autoClosingPairs: langConfiguration.autoClosingPairs,
215
216
  brackets: langConfiguration.brackets,
216
- comments: langConfiguration.comments,
217
+ // @monaco-uplift: Monaco doesn't support LineCommentRule yet, extract the string
218
+ comments: comments ? {
219
+ lineComment: comments.lineComment && typeof comments.lineComment === 'object' ? comments.lineComment.comment : comments.lineComment,
220
+ blockComment: comments.blockComment,
221
+ } : undefined,
217
222
  folding: this.convertFolding(langConfiguration.folding),
218
223
  surroundingPairs: langConfiguration.surroundingPairs,
219
224
  indentationRules: this.convertIndentationRules(langConfiguration.indentationRules),
@@ -26,7 +26,7 @@ import {
26
26
  noopWidgetStatusBarContribution,
27
27
  WidgetStatusBarContribution
28
28
  } from '@theia/core/lib/browser';
29
- import { MaybePromise, CommandContribution, ResourceResolver, bindRootContributionProvider, URI, generateUuid, PreferenceContribution } from '@theia/core/lib/common';
29
+ import { MaybePromise, CommandContribution, ResourceResolver, bindRootContributionProvider, URI, generateUuid, PreferenceContribution, nls } from '@theia/core/lib/common';
30
30
  import { WebSocketConnectionProvider } from '@theia/core/lib/browser/messaging';
31
31
  import { HostedPluginSupport } from '../../hosted/browser/hosted-plugin';
32
32
  import { HostedPluginWatcher } from '../../hosted/browser/hosted-plugin-watcher';
@@ -91,8 +91,10 @@ import { WebviewSecondaryWindowSupport } from './webview/webview-secondary-windo
91
91
  import { CustomEditorUndoRedoHandler } from './custom-editors/custom-editor-undo-redo-handler';
92
92
  import { CustomEditorNavigationContribution } from './custom-editors/custom-editor-navigation-contribution';
93
93
  import { bindWebviewPreferences } from '../common/webview-preferences';
94
+ import { bindPluginHostEnvironmentPreferences } from '../common/plugin-host-environment-preferences';
94
95
  import { WebviewFrontendPreferenceContribution } from './webview/webview-frontend-preference-contribution';
95
96
  import { PluginExtToolbarItemArgumentProcessor } from './plugin-ext-argument-processor';
97
+ import { WorkspaceRestriction, WorkspaceRestrictionContribution } from '@theia/workspace/lib/browser/workspace-trust-service';
96
98
 
97
99
  export default new ContainerModule((bind, unbind, isBound, rebind) => {
98
100
 
@@ -183,6 +185,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
183
185
  })).inSingletonScope();
184
186
 
185
187
  bindWebviewPreferences(bind);
188
+ bindPluginHostEnvironmentPreferences(bind);
186
189
  bind(WebviewFrontendPreferenceContribution).toSelf().inSingletonScope();
187
190
  bind(PreferenceContribution).toService(WebviewFrontendPreferenceContribution);
188
191
  bind(WebviewEnvironment).toSelf().inSingletonScope();
@@ -298,4 +301,31 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
298
301
  bind(PluginExtToolbarItemArgumentProcessor).toSelf().inSingletonScope();
299
302
  bind(ArgumentProcessorContribution).toService(PluginExtToolbarItemArgumentProcessor);
300
303
 
304
+ bind(WorkspaceRestrictionContribution).toDynamicValue(ctx => {
305
+ const hostedPlugin = ctx.container.get(HostedPluginSupport);
306
+ return {
307
+ getRestrictions(): WorkspaceRestriction[] {
308
+ if (hostedPlugin.disabledByTrust.size === 0) {
309
+ return [];
310
+ }
311
+ return [{
312
+ label: nls.localize('theia/plugin-ext/extensionsRestrictedMode',
313
+ 'Some extensions are disabled in Restricted Mode'),
314
+ details: Array.from(hostedPlugin.disabledByTrust)
315
+ }];
316
+ },
317
+ requiresReloadOnTrustChange(newTrust: boolean): boolean {
318
+ if (newTrust) {
319
+ // Granting trust: reload only if plugins were actually blocked.
320
+ return hostedPlugin.disabledByTrust.size > 0;
321
+ }
322
+ // Revoking trust: reload only if any loaded plugin declares supported: false,
323
+ // meaning it must be stopped now that the workspace is no longer trusted.
324
+ return hostedPlugin.plugins.some(
325
+ p => p.model.untrustedWorkspacesSupport === false
326
+ );
327
+ }
328
+ };
329
+ }).inSingletonScope();
330
+
301
331
  });
@@ -17,7 +17,7 @@
17
17
  import * as React from '@theia/core/shared/react';
18
18
  import { injectable, inject, postConstruct } from '@theia/core/shared/inversify';
19
19
  import { Message } from '@theia/core/shared/@lumino/messaging';
20
- import { PluginMetadata } from '../../common/plugin-protocol';
20
+ import { PluginIdentifiers, PluginMetadata } from '../../common/plugin-protocol';
21
21
  import { ReactWidget } from '@theia/core/lib/browser/widgets/react-widget';
22
22
  import { AlertMessage } from '@theia/core/lib/browser/widgets/alert-message';
23
23
  import { HostedPluginSupport, PluginProgressLocation } from '../../hosted/browser/hosted-plugin';
@@ -26,7 +26,7 @@ import { DisposableCollection } from '@theia/core/lib/common/disposable';
26
26
  import { codicon } from '@theia/core/lib/browser';
27
27
  import { nls } from '@theia/core/lib/common';
28
28
 
29
- export const PLUGINS_LABEL = nls.localize('theia/plugin-ext/plugins', 'Plugins');
29
+ export const PLUGINS_LABEL = nls.localizeByDefault('Plugins');
30
30
 
31
31
  @injectable()
32
32
  export class PluginWidget extends ReactWidget {
@@ -87,11 +87,18 @@ export class PluginWidget extends ReactWidget {
87
87
  }
88
88
 
89
89
  private renderPlugin(plugin: PluginMetadata): JSX.Element {
90
- return <div key={plugin.model.name} className={this.createPluginClassName(plugin)}>
90
+ const unversionedId = PluginIdentifiers.componentsToUnversionedId(plugin.model);
91
+ const isRestrictedByTrust = this.pluginService.disabledByTrust.has(unversionedId);
92
+ return <div key={plugin.model.name} className={this.createPluginClassName(plugin, isRestrictedByTrust)}>
91
93
  <div className='column flexcontainer pluginInformationContainer'>
92
94
  <div className='row flexcontainer'>
93
95
  <div className={codicon('list-selection')}></div>
94
96
  <div title={plugin.model.name} className='pluginName noWrapInfo'>{plugin.model.name}</div>
97
+ {isRestrictedByTrust && (
98
+ <span className='pluginRestrictedBadge' title={nls.localizeByDefault('Disabled in Restricted Mode')}>
99
+ {nls.localizeByDefault('Restricted Mode')}
100
+ </span>
101
+ )}
95
102
  </div>
96
103
  <div className='row flexcontainer'>
97
104
  <div className='pluginVersion'>{plugin.model.version}</div>
@@ -106,8 +113,11 @@ export class PluginWidget extends ReactWidget {
106
113
  </div>;
107
114
  }
108
115
 
109
- protected createPluginClassName(plugin: PluginMetadata): string {
116
+ protected createPluginClassName(plugin: PluginMetadata, isRestrictedByTrust: boolean = false): string {
110
117
  const classNames = ['pluginHeaderContainer'];
118
+ if (isRestrictedByTrust) {
119
+ classNames.push('pluginDisabledByTrust');
120
+ }
111
121
  return classNames.join(' ');
112
122
  }
113
123