@theia/plugin-ext 1.37.0-next.8 → 1.37.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/common/language-pack-service.d.ts +16 -0
- package/lib/common/language-pack-service.d.ts.map +1 -0
- package/lib/common/language-pack-service.js +21 -0
- package/lib/common/language-pack-service.js.map +1 -0
- package/lib/common/plugin-api-rpc-model.d.ts +6 -0
- package/lib/common/plugin-api-rpc-model.d.ts.map +1 -1
- package/lib/common/plugin-api-rpc-model.js +6 -1
- package/lib/common/plugin-api-rpc-model.js.map +1 -1
- package/lib/common/plugin-api-rpc.d.ts +22 -1
- package/lib/common/plugin-api-rpc.d.ts.map +1 -1
- package/lib/common/plugin-api-rpc.js +2 -1
- package/lib/common/plugin-api-rpc.js.map +1 -1
- package/lib/common/plugin-protocol.d.ts +2 -0
- package/lib/common/plugin-protocol.d.ts.map +1 -1
- package/lib/common/plugin-protocol.js.map +1 -1
- package/lib/hosted/browser/hosted-plugin.d.ts +6 -2
- package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
- package/lib/hosted/browser/hosted-plugin.js +26 -5
- package/lib/hosted/browser/hosted-plugin.js.map +1 -1
- package/lib/hosted/browser/worker/worker-main.js +4 -2
- package/lib/hosted/browser/worker/worker-main.js.map +1 -1
- package/lib/hosted/node/hosted-plugin-deployer-handler.js +2 -2
- package/lib/hosted/node/hosted-plugin-deployer-handler.js.map +1 -1
- package/lib/hosted/node/hosted-plugin-localization-service.d.ts +13 -1
- package/lib/hosted/node/hosted-plugin-localization-service.d.ts.map +1 -1
- package/lib/hosted/node/hosted-plugin-localization-service.js +122 -10
- package/lib/hosted/node/hosted-plugin-localization-service.js.map +1 -1
- package/lib/hosted/node/plugin-ext-hosted-backend-module.d.ts.map +1 -1
- package/lib/hosted/node/plugin-ext-hosted-backend-module.js +7 -0
- package/lib/hosted/node/plugin-ext-hosted-backend-module.js.map +1 -1
- package/lib/hosted/node/plugin-host-rpc.d.ts +2 -2
- package/lib/hosted/node/plugin-host-rpc.d.ts.map +1 -1
- package/lib/hosted/node/plugin-host-rpc.js +6 -4
- package/lib/hosted/node/plugin-host-rpc.js.map +1 -1
- package/lib/hosted/node/plugin-language-pack-service.d.ts +8 -0
- package/lib/hosted/node/plugin-language-pack-service.d.ts.map +1 -0
- package/lib/hosted/node/plugin-language-pack-service.js +54 -0
- package/lib/hosted/node/plugin-language-pack-service.js.map +1 -0
- package/lib/hosted/node/scanners/scanner-theia.d.ts.map +1 -1
- package/lib/hosted/node/scanners/scanner-theia.js +1 -0
- package/lib/hosted/node/scanners/scanner-theia.js.map +1 -1
- package/lib/main/browser/comments/comment-thread-widget.d.ts.map +1 -1
- package/lib/main/browser/comments/comment-thread-widget.js +5 -1
- package/lib/main/browser/comments/comment-thread-widget.js.map +1 -1
- package/lib/main/browser/comments/comments-main.d.ts +6 -1
- package/lib/main/browser/comments/comments-main.d.ts.map +1 -1
- package/lib/main/browser/comments/comments-main.js +15 -0
- package/lib/main/browser/comments/comments-main.js.map +1 -1
- package/lib/main/browser/localization-main.d.ts +9 -0
- package/lib/main/browser/localization-main.d.ts.map +1 -0
- package/lib/main/browser/localization-main.js +32 -0
- package/lib/main/browser/localization-main.js.map +1 -0
- package/lib/main/browser/main-context.d.ts.map +1 -1
- package/lib/main/browser/main-context.js +3 -0
- package/lib/main/browser/main-context.js.map +1 -1
- package/lib/main/browser/plugin-ext-frontend-module.d.ts.map +1 -1
- package/lib/main/browser/plugin-ext-frontend-module.js +5 -0
- package/lib/main/browser/plugin-ext-frontend-module.js.map +1 -1
- package/lib/main/browser/view/tree-view-widget.d.ts.map +1 -1
- package/lib/main/browser/view/tree-view-widget.js +10 -1
- package/lib/main/browser/view/tree-view-widget.js.map +1 -1
- package/lib/main/electron-browser/webview/electron-webview-widget-factory.d.ts +1 -0
- package/lib/main/electron-browser/webview/electron-webview-widget-factory.d.ts.map +1 -1
- package/lib/main/electron-browser/webview/electron-webview-widget-factory.js +4 -15
- package/lib/main/electron-browser/webview/electron-webview-widget-factory.js.map +1 -1
- package/lib/main/node/plugin-github-resolver.d.ts +3 -1
- package/lib/main/node/plugin-github-resolver.d.ts.map +1 -1
- package/lib/main/node/plugin-github-resolver.js +64 -71
- package/lib/main/node/plugin-github-resolver.js.map +1 -1
- package/lib/main/node/plugin-http-resolver.d.ts +2 -0
- package/lib/main/node/plugin-http-resolver.d.ts.map +1 -1
- package/lib/main/node/plugin-http-resolver.js +31 -31
- package/lib/main/node/plugin-http-resolver.js.map +1 -1
- package/lib/main/node/plugins-key-value-storage.js +1 -1
- package/lib/main/node/plugins-key-value-storage.js.map +1 -1
- package/lib/plugin/comments.d.ts +3 -0
- package/lib/plugin/comments.d.ts.map +1 -1
- package/lib/plugin/comments.js +24 -0
- package/lib/plugin/comments.js.map +1 -1
- package/lib/plugin/localization-ext.d.ts +17 -0
- package/lib/plugin/localization-ext.d.ts.map +1 -0
- package/lib/plugin/localization-ext.js +74 -0
- package/lib/plugin/localization-ext.js.map +1 -0
- package/lib/plugin/output-channel/log-output-channel.d.ts +24 -0
- package/lib/plugin/output-channel/log-output-channel.d.ts.map +1 -0
- package/lib/plugin/output-channel/log-output-channel.js +92 -0
- package/lib/plugin/output-channel/log-output-channel.js.map +1 -0
- package/lib/plugin/output-channel/output-channel-item.d.ts +3 -3
- package/lib/plugin/output-channel/output-channel-item.d.ts.map +1 -1
- package/lib/plugin/output-channel/output-channel-item.js.map +1 -1
- package/lib/plugin/output-channel-registry.d.ts +7 -2
- package/lib/plugin/output-channel-registry.d.ts.map +1 -1
- package/lib/plugin/output-channel-registry.js +15 -6
- package/lib/plugin/output-channel-registry.js.map +1 -1
- package/lib/plugin/plugin-context.d.ts +2 -1
- package/lib/plugin/plugin-context.d.ts.map +1 -1
- package/lib/plugin/plugin-context.js +26 -3
- package/lib/plugin/plugin-context.js.map +1 -1
- package/lib/plugin/plugin-manager.d.ts +3 -2
- package/lib/plugin/plugin-manager.d.ts.map +1 -1
- package/lib/plugin/plugin-manager.js +4 -1
- package/lib/plugin/plugin-manager.js.map +1 -1
- package/lib/plugin/preference-registry.d.ts +1 -1
- package/lib/plugin/preference-registry.js +1 -1
- package/lib/plugin/stubs/tests-api.d.ts +2 -1
- package/lib/plugin/stubs/tests-api.d.ts.map +1 -1
- package/lib/plugin/stubs/tests-api.js +2 -1
- package/lib/plugin/stubs/tests-api.js.map +1 -1
- package/lib/plugin/tree/tree-views.d.ts +2 -0
- package/lib/plugin/tree/tree-views.d.ts.map +1 -1
- package/lib/plugin/tree/tree-views.js +10 -3
- package/lib/plugin/tree/tree-views.js.map +1 -1
- package/lib/plugin/type-converters.d.ts.map +1 -1
- package/lib/plugin/type-converters.js +6 -3
- package/lib/plugin/type-converters.js.map +1 -1
- package/lib/plugin/types-impl.d.ts +8 -4
- package/lib/plugin/types-impl.d.ts.map +1 -1
- package/lib/plugin/types-impl.js +12 -7
- package/lib/plugin/types-impl.js.map +1 -1
- package/package.json +28 -30
- package/src/common/language-pack-service.ts +34 -0
- package/src/common/plugin-api-rpc-model.ts +7 -0
- package/src/common/plugin-api-rpc.ts +25 -2
- package/src/common/plugin-protocol.ts +2 -0
- package/src/hosted/browser/hosted-plugin.ts +27 -6
- package/src/hosted/browser/worker/worker-main.ts +5 -2
- package/src/hosted/node/hosted-plugin-deployer-handler.ts +2 -2
- package/src/hosted/node/hosted-plugin-localization-service.ts +132 -11
- package/src/hosted/node/plugin-ext-hosted-backend-module.ts +12 -0
- package/src/hosted/node/plugin-host-rpc.ts +8 -5
- package/src/hosted/node/plugin-language-pack-service.ts +43 -0
- package/src/hosted/node/scanners/scanner-theia.ts +1 -0
- package/src/main/browser/comments/comment-thread-widget.tsx +6 -1
- package/src/main/browser/comments/comments-main.ts +18 -1
- package/src/main/browser/localization-main.ts +34 -0
- package/src/main/browser/main-context.ts +4 -0
- package/src/main/browser/plugin-ext-frontend-module.ts +6 -0
- package/src/main/browser/view/tree-view-widget.tsx +11 -1
- package/src/main/electron-browser/webview/electron-webview-widget-factory.ts +4 -15
- package/src/main/node/plugin-github-resolver.ts +65 -81
- package/src/main/node/plugin-http-resolver.ts +29 -35
- package/src/main/node/plugins-key-value-storage.ts +1 -1
- package/src/plugin/comments.ts +32 -1
- package/src/plugin/localization-ext.ts +84 -0
- package/src/plugin/output-channel/log-output-channel.ts +108 -0
- package/src/plugin/output-channel/output-channel-item.ts +2 -2
- package/src/plugin/output-channel-registry.ts +20 -7
- package/src/plugin/plugin-context.ts +31 -3
- package/src/plugin/plugin-manager.ts +5 -1
- package/src/plugin/preference-registry.ts +1 -1
- package/src/plugin/stubs/tests-api.ts +3 -1
- package/src/plugin/tree/tree-views.ts +12 -3
- package/src/plugin/type-converters.ts +5 -3
- package/src/plugin/types-impl.ts +8 -3
- package/LICENSE +0 -642
|
@@ -49,7 +49,8 @@ import { WaitUntilEvent } from '@theia/core/lib/common/event';
|
|
|
49
49
|
import { FileSearchService } from '@theia/file-search/lib/common/file-search-service';
|
|
50
50
|
import { FrontendApplicationStateService } from '@theia/core/lib/browser/frontend-application-state';
|
|
51
51
|
import { PluginViewRegistry } from '../../main/browser/view/plugin-view-registry';
|
|
52
|
-
import { TaskProviderRegistry, TaskResolverRegistry } from '@theia/task/lib/browser/task-contribution';
|
|
52
|
+
import { WillResolveTaskProvider, TaskProviderRegistry, TaskResolverRegistry } from '@theia/task/lib/browser/task-contribution';
|
|
53
|
+
import { TaskDefinitionRegistry } from '@theia/task/lib/browser/task-definition-registry';
|
|
53
54
|
import { WebviewEnvironment } from '../../main/browser/webview/webview-environment';
|
|
54
55
|
import { WebviewWidget } from '../../main/browser/webview/webview';
|
|
55
56
|
import { WidgetManager } from '@theia/core/lib/browser/widget-manager';
|
|
@@ -73,6 +74,7 @@ export type PluginHost = 'frontend' | string;
|
|
|
73
74
|
export type DebugActivationEvent = 'onDebugResolve' | 'onDebugInitialConfigurations' | 'onDebugAdapterProtocolTracker' | 'onDebugDynamicConfigurations';
|
|
74
75
|
|
|
75
76
|
export const PluginProgressLocation = 'plugin';
|
|
77
|
+
export const ALL_ACTIVATION_EVENT = '*';
|
|
76
78
|
|
|
77
79
|
@injectable()
|
|
78
80
|
export class HostedPluginSupport {
|
|
@@ -139,6 +141,9 @@ export class HostedPluginSupport {
|
|
|
139
141
|
@inject(TaskResolverRegistry)
|
|
140
142
|
protected readonly taskResolverRegistry: TaskResolverRegistry;
|
|
141
143
|
|
|
144
|
+
@inject(TaskDefinitionRegistry)
|
|
145
|
+
protected readonly taskDefinitionRegistry: TaskDefinitionRegistry;
|
|
146
|
+
|
|
142
147
|
@inject(ProgressService)
|
|
143
148
|
protected readonly progressService: ProgressService;
|
|
144
149
|
|
|
@@ -205,7 +210,7 @@ export class HostedPluginSupport {
|
|
|
205
210
|
this.debugSessionManager.onWillResolveDebugConfiguration(event => this.ensureDebugActivation(event, 'onDebugResolve', event.debugType));
|
|
206
211
|
this.debugConfigurationManager.onWillProvideDebugConfiguration(event => this.ensureDebugActivation(event, 'onDebugInitialConfigurations'));
|
|
207
212
|
// Activate all providers of dynamic configurations, i.e. Let the user pick a configuration from all the available ones.
|
|
208
|
-
this.debugConfigurationManager.onWillProvideDynamicDebugConfiguration(event => this.ensureDebugActivation(event, 'onDebugDynamicConfigurations',
|
|
213
|
+
this.debugConfigurationManager.onWillProvideDynamicDebugConfiguration(event => this.ensureDebugActivation(event, 'onDebugDynamicConfigurations', ALL_ACTIVATION_EVENT));
|
|
209
214
|
this.viewRegistry.onDidExpandView(id => this.activateByView(id));
|
|
210
215
|
this.taskProviderRegistry.onWillProvideTaskProvider(event => this.ensureTaskActivation(event));
|
|
211
216
|
this.taskResolverRegistry.onWillProvideTaskResolver(event => this.ensureTaskActivation(event));
|
|
@@ -510,7 +515,7 @@ export class HostedPluginSupport {
|
|
|
510
515
|
workspaceState,
|
|
511
516
|
env: {
|
|
512
517
|
queryParams: getQueryParameters(),
|
|
513
|
-
language: nls.locale ||
|
|
518
|
+
language: nls.locale || nls.defaultLocale,
|
|
514
519
|
shell: defaultShell,
|
|
515
520
|
uiKind: isElectron ? UIKind.Desktop : UIKind.Web,
|
|
516
521
|
appName: FrontendApplicationConfigProvider.get().applicationName,
|
|
@@ -610,6 +615,10 @@ export class HostedPluginSupport {
|
|
|
610
615
|
await this.activateByEvent(`onCommand:${commandId}`);
|
|
611
616
|
}
|
|
612
617
|
|
|
618
|
+
async activateByTaskType(taskType: string): Promise<void> {
|
|
619
|
+
await this.activateByEvent(`onTaskType:${taskType}`);
|
|
620
|
+
}
|
|
621
|
+
|
|
613
622
|
async activateByCustomEditor(viewType: string): Promise<void> {
|
|
614
623
|
await this.activateByEvent(`onCustomEditor:${viewType}`);
|
|
615
624
|
}
|
|
@@ -648,8 +657,20 @@ export class HostedPluginSupport {
|
|
|
648
657
|
event.waitUntil(p);
|
|
649
658
|
}
|
|
650
659
|
|
|
651
|
-
protected ensureTaskActivation(event:
|
|
652
|
-
|
|
660
|
+
protected ensureTaskActivation(event: WillResolveTaskProvider): void {
|
|
661
|
+
const promises = [this.activateByCommand('workbench.action.tasks.runTask')];
|
|
662
|
+
const taskType = event.taskType;
|
|
663
|
+
if (taskType) {
|
|
664
|
+
if (taskType === ALL_ACTIVATION_EVENT) {
|
|
665
|
+
for (const taskDefinition of this.taskDefinitionRegistry.getAll()) {
|
|
666
|
+
promises.push(this.activateByTaskType(taskDefinition.taskType));
|
|
667
|
+
}
|
|
668
|
+
} else {
|
|
669
|
+
promises.push(this.activateByTaskType(taskType));
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
event.waitUntil(Promise.all(promises));
|
|
653
674
|
}
|
|
654
675
|
|
|
655
676
|
protected ensureDebugActivation(event: WaitUntilEvent, activationEvent?: DebugActivationEvent, debugType?: string): void {
|
|
@@ -678,7 +699,7 @@ export class HostedPluginSupport {
|
|
|
678
699
|
for (const activationEvent of activationEvents) {
|
|
679
700
|
if (/^workspaceContains:/.test(activationEvent)) {
|
|
680
701
|
const fileNameOrGlob = activationEvent.substr('workspaceContains:'.length);
|
|
681
|
-
if (fileNameOrGlob.indexOf(
|
|
702
|
+
if (fileNameOrGlob.indexOf(ALL_ACTIVATION_EVENT) >= 0 || fileNameOrGlob.indexOf('?') >= 0) {
|
|
682
703
|
includePatterns.push(fileNameOrGlob);
|
|
683
704
|
} else {
|
|
684
705
|
paths.push(fileNameOrGlob);
|
|
@@ -36,6 +36,7 @@ import { WorkspaceExtImpl } from '../../../plugin/workspace';
|
|
|
36
36
|
import { createDebugExtStub } from './debug-stub';
|
|
37
37
|
import { loadManifest } from './plugin-manifest-loader';
|
|
38
38
|
import { WorkerEnvExtImpl } from './worker-env-ext';
|
|
39
|
+
import { LocalizationExtImpl } from '../../../plugin/localization-ext';
|
|
39
40
|
|
|
40
41
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
41
42
|
const ctx = self as any;
|
|
@@ -77,6 +78,7 @@ const debugExt = createDebugExtStub(rpc);
|
|
|
77
78
|
const clipboardExt = new ClipboardExt(rpc);
|
|
78
79
|
const webviewExt = new WebviewsExtImpl(rpc, workspaceExt);
|
|
79
80
|
const secretsExt = new SecretsExtImpl(rpc);
|
|
81
|
+
const localizationExt = new LocalizationExtImpl(rpc);
|
|
80
82
|
const terminalService: TerminalServiceExt = new TerminalServiceExtImpl(rpc);
|
|
81
83
|
|
|
82
84
|
const pluginManager = new PluginManagerExtImpl({
|
|
@@ -171,7 +173,7 @@ const pluginManager = new PluginManagerExtImpl({
|
|
|
171
173
|
}
|
|
172
174
|
}
|
|
173
175
|
}
|
|
174
|
-
}, envExt, terminalService, storageProxy, secretsExt, preferenceRegistryExt, webviewExt, rpc);
|
|
176
|
+
}, envExt, terminalService, storageProxy, secretsExt, preferenceRegistryExt, webviewExt, localizationExt, rpc);
|
|
175
177
|
|
|
176
178
|
const apiFactory = createAPIFactory(
|
|
177
179
|
rpc,
|
|
@@ -183,7 +185,8 @@ const apiFactory = createAPIFactory(
|
|
|
183
185
|
workspaceExt,
|
|
184
186
|
messageRegistryExt,
|
|
185
187
|
clipboardExt,
|
|
186
|
-
webviewExt
|
|
188
|
+
webviewExt,
|
|
189
|
+
localizationExt
|
|
187
190
|
);
|
|
188
191
|
let defaultApi: typeof theia;
|
|
189
192
|
|
|
@@ -133,7 +133,7 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
|
|
|
133
133
|
if (await this.deployPlugin(plugin, 'backend')) { successes++; }
|
|
134
134
|
}
|
|
135
135
|
// rebuild translation config after deployment
|
|
136
|
-
this.localizationService.buildTranslationConfig([...this.deployedBackendPlugins.values()]);
|
|
136
|
+
await this.localizationService.buildTranslationConfig([...this.deployedBackendPlugins.values()]);
|
|
137
137
|
// resolve on first deploy
|
|
138
138
|
this.backendPluginsMetadataDeferred.resolve(undefined);
|
|
139
139
|
return successes;
|
|
@@ -174,7 +174,7 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
|
|
|
174
174
|
const { type } = entry;
|
|
175
175
|
const deployed: DeployedPlugin = { metadata, type };
|
|
176
176
|
deployed.contributes = this.reader.readContribution(manifest);
|
|
177
|
-
this.localizationService.deployLocalizations(deployed);
|
|
177
|
+
await this.localizationService.deployLocalizations(deployed);
|
|
178
178
|
deployedPlugins.set(id, deployed);
|
|
179
179
|
deployPlugin.debug(`Deployed ${entryPoint} plugin "${id}" from "${metadata.model.entryPoint[entryPoint] || pluginPath}"`);
|
|
180
180
|
} catch (e) {
|
|
@@ -19,12 +19,12 @@ import * as fs from '@theia/core/shared/fs-extra';
|
|
|
19
19
|
import { LocalizationProvider } from '@theia/core/lib/node/i18n/localization-provider';
|
|
20
20
|
import { Localization } from '@theia/core/lib/common/i18n/localization';
|
|
21
21
|
import { inject, injectable } from '@theia/core/shared/inversify';
|
|
22
|
-
import { DeployedPlugin, Localization as PluginLocalization, PluginIdentifiers } from '../../common';
|
|
23
|
-
import { URI } from '@theia/core/shared/vscode-uri';
|
|
22
|
+
import { DeployedPlugin, Localization as PluginLocalization, PluginIdentifiers, Translation } from '../../common';
|
|
24
23
|
import { EnvVariablesServer } from '@theia/core/lib/common/env-variables';
|
|
25
24
|
import { BackendApplicationContribution } from '@theia/core/lib/node';
|
|
26
|
-
import { Disposable, isObject, MaybePromise } from '@theia/core';
|
|
25
|
+
import { Disposable, DisposableCollection, isObject, MaybePromise, nls, URI } from '@theia/core';
|
|
27
26
|
import { Deferred } from '@theia/core/lib/common/promise-util';
|
|
27
|
+
import { LanguagePackBundle, LanguagePackService } from '../../common/language-pack-service';
|
|
28
28
|
|
|
29
29
|
export interface VSCodeNlsConfig {
|
|
30
30
|
locale: string
|
|
@@ -42,6 +42,9 @@ export class HostedPluginLocalizationService implements BackendApplicationContri
|
|
|
42
42
|
@inject(LocalizationProvider)
|
|
43
43
|
protected readonly localizationProvider: LocalizationProvider;
|
|
44
44
|
|
|
45
|
+
@inject(LanguagePackService)
|
|
46
|
+
protected readonly languagePackService: LanguagePackService;
|
|
47
|
+
|
|
45
48
|
@inject(EnvVariablesServer)
|
|
46
49
|
protected readonly envVariables: EnvVariablesServer;
|
|
47
50
|
|
|
@@ -62,26 +65,93 @@ export class HostedPluginLocalizationService implements BackendApplicationContri
|
|
|
62
65
|
.then(() => this._ready.resolve());
|
|
63
66
|
}
|
|
64
67
|
|
|
65
|
-
deployLocalizations(plugin: DeployedPlugin): void {
|
|
68
|
+
async deployLocalizations(plugin: DeployedPlugin): Promise<void> {
|
|
69
|
+
const disposable = new DisposableCollection();
|
|
66
70
|
if (plugin.contributes?.localizations) {
|
|
71
|
+
// Indicator that this plugin is a vscode language pack
|
|
72
|
+
// Language packs translate Theia and some builtin vscode extensions
|
|
67
73
|
const localizations = buildLocalizations(plugin.contributes.localizations);
|
|
68
|
-
|
|
69
|
-
this.localizationDisposeMap.set(versionedId, Disposable.create(() => {
|
|
74
|
+
disposable.push(Disposable.create(() => {
|
|
70
75
|
this.localizationProvider.removeLocalizations(...localizations);
|
|
71
|
-
this.localizationDisposeMap.delete(versionedId);
|
|
72
76
|
}));
|
|
73
77
|
this.localizationProvider.addLocalizations(...localizations);
|
|
74
78
|
}
|
|
79
|
+
if (plugin.metadata.model.l10n || plugin.contributes?.localizations) {
|
|
80
|
+
// Indicator that this plugin is a vscode language pack or has its own localization bundles
|
|
81
|
+
// These bundles are purely used for translating plugins
|
|
82
|
+
// The branch above builds localizations for Theia's own strings
|
|
83
|
+
disposable.push(await this.updateLanguagePackBundles(plugin));
|
|
84
|
+
}
|
|
85
|
+
if (!disposable.disposed) {
|
|
86
|
+
const versionedId = PluginIdentifiers.componentsToVersionedId(plugin.metadata.model);
|
|
87
|
+
disposable.push(Disposable.create(() => {
|
|
88
|
+
this.localizationDisposeMap.delete(versionedId);
|
|
89
|
+
}));
|
|
90
|
+
this.localizationDisposeMap.set(versionedId, disposable);
|
|
91
|
+
}
|
|
75
92
|
}
|
|
76
93
|
|
|
77
94
|
undeployLocalizations(plugin: PluginIdentifiers.VersionedId): void {
|
|
78
95
|
this.localizationDisposeMap.get(plugin)?.dispose();
|
|
79
96
|
}
|
|
80
97
|
|
|
98
|
+
protected async updateLanguagePackBundles(plugin: DeployedPlugin): Promise<Disposable> {
|
|
99
|
+
const disposable = new DisposableCollection();
|
|
100
|
+
const pluginId = plugin.metadata.model.id;
|
|
101
|
+
const packageUri = new URI(plugin.metadata.model.packageUri);
|
|
102
|
+
if (plugin.contributes?.localizations) {
|
|
103
|
+
for (const localization of plugin.contributes.localizations) {
|
|
104
|
+
for (const translation of localization.translations) {
|
|
105
|
+
const l10n = getL10nTranslation(translation);
|
|
106
|
+
if (l10n) {
|
|
107
|
+
const translatedPluginId = translation.id;
|
|
108
|
+
const translationUri = packageUri.resolve(translation.path);
|
|
109
|
+
const locale = localization.languageId;
|
|
110
|
+
// We store a bundle for another extension in here
|
|
111
|
+
// Hence we use `translatedPluginId` instead of `pluginId`
|
|
112
|
+
this.languagePackService.storeBundle(translatedPluginId, locale, {
|
|
113
|
+
contents: processL10nBundle(l10n),
|
|
114
|
+
uri: translationUri.toString()
|
|
115
|
+
});
|
|
116
|
+
disposable.push(Disposable.create(() => {
|
|
117
|
+
// Only dispose the deleted locale for the specific plugin
|
|
118
|
+
this.languagePackService.deleteBundle(translatedPluginId, locale);
|
|
119
|
+
}));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// The `l10n` field of the plugin model points to a relative directory path within the plugin
|
|
125
|
+
// It is supposed to contain localization bundles that contain translations of the plugin strings into different languages
|
|
126
|
+
if (plugin.metadata.model.l10n) {
|
|
127
|
+
const bundleDirectory = packageUri.resolve(plugin.metadata.model.l10n);
|
|
128
|
+
const bundles = await loadPluginBundles(bundleDirectory);
|
|
129
|
+
if (bundles) {
|
|
130
|
+
for (const [locale, bundle] of Object.entries(bundles)) {
|
|
131
|
+
this.languagePackService.storeBundle(pluginId, locale, bundle);
|
|
132
|
+
}
|
|
133
|
+
disposable.push(Disposable.create(() => {
|
|
134
|
+
// Dispose all bundles contributed by the deleted plugin
|
|
135
|
+
this.languagePackService.deleteBundle(pluginId);
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return disposable;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Performs localization of the plugin model. Translates entries such as command names, view names and other items.
|
|
144
|
+
*
|
|
145
|
+
* Translatable items are indicated with a `%id%` value.
|
|
146
|
+
* The `id` is the translation key that gets replaced with the localized value for the currently selected language.
|
|
147
|
+
*
|
|
148
|
+
* Returns a copy of the plugin argument and does not modify the argument.
|
|
149
|
+
* This is done to preserve the original `%id%` values for subsequent invocations of this method.
|
|
150
|
+
*/
|
|
81
151
|
async localizePlugin(plugin: DeployedPlugin): Promise<DeployedPlugin> {
|
|
82
152
|
const currentLanguage = this.localizationProvider.getCurrentLanguage();
|
|
83
153
|
const localization = this.localizationProvider.loadLocalization(currentLanguage);
|
|
84
|
-
const pluginPath = URI
|
|
154
|
+
const pluginPath = new URI(plugin.metadata.model.packageUri).path.fsPath();
|
|
85
155
|
const pluginId = plugin.metadata.model.id;
|
|
86
156
|
try {
|
|
87
157
|
const translations = await loadPackageTranslations(pluginPath, currentLanguage);
|
|
@@ -98,7 +168,7 @@ export class HostedPluginLocalizationService implements BackendApplicationContri
|
|
|
98
168
|
getNlsConfig(): VSCodeNlsConfig {
|
|
99
169
|
const locale = this.localizationProvider.getCurrentLanguage();
|
|
100
170
|
const configFile = this.translationConfigFiles.get(locale);
|
|
101
|
-
if (locale ===
|
|
171
|
+
if (locale === nls.defaultLocale || !configFile) {
|
|
102
172
|
return { locale, availableLanguages: {} };
|
|
103
173
|
}
|
|
104
174
|
const cache = path.dirname(configFile);
|
|
@@ -118,7 +188,7 @@ export class HostedPluginLocalizationService implements BackendApplicationContri
|
|
|
118
188
|
const configs = new Map<string, Record<string, string>>();
|
|
119
189
|
for (const plugin of plugins) {
|
|
120
190
|
if (plugin.contributes?.localizations) {
|
|
121
|
-
const pluginPath = URI
|
|
191
|
+
const pluginPath = new URI(plugin.metadata.model.packageUri).path.fsPath();
|
|
122
192
|
for (const localization of plugin.contributes.localizations) {
|
|
123
193
|
const config = configs.get(localization.languageId) || {};
|
|
124
194
|
for (const translation of localization.translations) {
|
|
@@ -140,12 +210,59 @@ export class HostedPluginLocalizationService implements BackendApplicationContri
|
|
|
140
210
|
}
|
|
141
211
|
|
|
142
212
|
protected async getLocalizationCacheDir(): Promise<string> {
|
|
143
|
-
const configDir = URI
|
|
213
|
+
const configDir = new URI(await this.envVariables.getConfigDirUri()).path.fsPath();
|
|
144
214
|
const cacheDir = path.join(configDir, 'localization-cache');
|
|
145
215
|
return cacheDir;
|
|
146
216
|
}
|
|
147
217
|
}
|
|
148
218
|
|
|
219
|
+
// New plugin localization logic using vscode.l10n
|
|
220
|
+
|
|
221
|
+
function getL10nTranslation(translation: Translation): UnprocessedL10nBundle | undefined {
|
|
222
|
+
// 'bundle' is a special key that contains all translations for the l10n vscode API
|
|
223
|
+
// If that doesn't exist, we can assume that the language pack is using the old vscode-nls API
|
|
224
|
+
return translation.contents.bundle;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
async function loadPluginBundles(l10nUri: URI): Promise<Record<string, LanguagePackBundle> | undefined> {
|
|
228
|
+
try {
|
|
229
|
+
const directory = l10nUri.path.fsPath();
|
|
230
|
+
const files = await fs.readdir(directory);
|
|
231
|
+
const result: Record<string, LanguagePackBundle> = {};
|
|
232
|
+
await Promise.all(files.map(async fileName => {
|
|
233
|
+
const match = fileName.match(/^bundle\.l10n\.([\w\-]+)\.json$/);
|
|
234
|
+
if (match) {
|
|
235
|
+
const locale = match[1];
|
|
236
|
+
const contents = await fs.readJSON(path.join(directory, fileName));
|
|
237
|
+
result[locale] = {
|
|
238
|
+
contents,
|
|
239
|
+
uri: l10nUri.resolve(fileName).toString()
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
}));
|
|
243
|
+
return result;
|
|
244
|
+
} catch (err) {
|
|
245
|
+
// The directory either doesn't exist or its contents cannot be parsed
|
|
246
|
+
console.error(`Failed to load plugin localization bundles from ${l10nUri}.`, err);
|
|
247
|
+
// In any way we should just safely return undefined
|
|
248
|
+
return undefined;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
type UnprocessedL10nBundle = Record<string, string | { message: string }>;
|
|
253
|
+
|
|
254
|
+
function processL10nBundle(bundle: UnprocessedL10nBundle): Record<string, string> {
|
|
255
|
+
const processedBundle: Record<string, string> = {};
|
|
256
|
+
for (const [name, value] of Object.entries(bundle)) {
|
|
257
|
+
const stringValue = typeof value === 'string' ? value : value.message;
|
|
258
|
+
processedBundle[name] = stringValue;
|
|
259
|
+
}
|
|
260
|
+
return processedBundle;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Old plugin localization logic for vscode-nls
|
|
264
|
+
// vscode-nls was used until version 1.73 of VSCode to translate extensions
|
|
265
|
+
|
|
149
266
|
function buildLocalizations(localizations: PluginLocalization[]): Localization[] {
|
|
150
267
|
const theiaLocalizations: Localization[] = [];
|
|
151
268
|
for (const localization of localizations) {
|
|
@@ -173,6 +290,10 @@ function buildTranslationKey(pluginId: string, scope: string, key: string): stri
|
|
|
173
290
|
return `${pluginId}/${Localization.transformKey(scope)}/${key}`;
|
|
174
291
|
}
|
|
175
292
|
|
|
293
|
+
// Localization logic for `package.json` entries
|
|
294
|
+
// Extensions can use `package.nls.json` files to store translations for values in their package.json
|
|
295
|
+
// This logic has not changed with the introduction of the vscode.l10n API
|
|
296
|
+
|
|
176
297
|
interface PackageTranslation {
|
|
177
298
|
translation?: Record<string, string>
|
|
178
299
|
default?: Record<string, string>
|
|
@@ -34,6 +34,10 @@ import { HostedPluginDeployerHandler } from './hosted-plugin-deployer-handler';
|
|
|
34
34
|
import { PluginUriFactory } from './scanners/plugin-uri-factory';
|
|
35
35
|
import { FilePluginUriFactory } from './scanners/file-plugin-uri-factory';
|
|
36
36
|
import { HostedPluginLocalizationService } from './hosted-plugin-localization-service';
|
|
37
|
+
import { LanguagePackService, languagePackServicePath } from '../../common/language-pack-service';
|
|
38
|
+
import { PluginLanguagePackService } from './plugin-language-pack-service';
|
|
39
|
+
import { JsonRpcConnectionHandler } from '@theia/core/lib/common/messaging/proxy-factory';
|
|
40
|
+
import { ConnectionHandler } from '@theia/core/lib/common/messaging/handler';
|
|
37
41
|
|
|
38
42
|
const commonHostedConnectionModule = ConnectionContainerModule.create(({ bind, bindBackendService }) => {
|
|
39
43
|
bind(HostedPluginProcess).toSelf().inSingletonScope();
|
|
@@ -64,6 +68,14 @@ export function bindCommonHostedBackend(bind: interfaces.Bind): void {
|
|
|
64
68
|
bind(HostedPluginDeployerHandler).toSelf().inSingletonScope();
|
|
65
69
|
bind(PluginDeployerHandler).toService(HostedPluginDeployerHandler);
|
|
66
70
|
|
|
71
|
+
bind(PluginLanguagePackService).toSelf().inSingletonScope();
|
|
72
|
+
bind(LanguagePackService).toService(PluginLanguagePackService);
|
|
73
|
+
bind(ConnectionHandler).toDynamicValue(ctx =>
|
|
74
|
+
new JsonRpcConnectionHandler(languagePackServicePath, () =>
|
|
75
|
+
ctx.container.get(LanguagePackService)
|
|
76
|
+
)
|
|
77
|
+
).inSingletonScope();
|
|
78
|
+
|
|
67
79
|
bind(GrammarsReader).toSelf().inSingletonScope();
|
|
68
80
|
bind(HostedPluginProcessConfiguration).toConstantValue({
|
|
69
81
|
path: path.join(__dirname, 'plugin-host'),
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import { dynamicRequire } from '@theia/core/lib/node/dynamic-require';
|
|
18
18
|
import { PluginManagerExtImpl } from '../../plugin/plugin-manager';
|
|
19
|
-
import { MAIN_RPC_CONTEXT, Plugin, PluginAPIFactory } from '../../common/plugin-api-rpc';
|
|
19
|
+
import { LocalizationExt, MAIN_RPC_CONTEXT, Plugin, PluginAPIFactory } from '../../common/plugin-api-rpc';
|
|
20
20
|
import { PluginMetadata } from '../../common/plugin-protocol';
|
|
21
21
|
import { createAPIFactory } from '../../plugin/plugin-context';
|
|
22
22
|
import { EnvExtImpl } from '../../plugin/env';
|
|
@@ -35,6 +35,7 @@ import { TerminalServiceExtImpl } from '../../plugin/terminal-ext';
|
|
|
35
35
|
import { SecretsExtImpl } from '../../plugin/secrets-ext';
|
|
36
36
|
import { BackendInitializationFn } from '../../common';
|
|
37
37
|
import { connectProxyResolver } from './plugin-host-proxy';
|
|
38
|
+
import { LocalizationExtImpl } from '../../plugin/localization-ext';
|
|
38
39
|
|
|
39
40
|
/**
|
|
40
41
|
* Handle the RPC calls.
|
|
@@ -61,7 +62,8 @@ export class PluginHostRPC {
|
|
|
61
62
|
const webviewExt = new WebviewsExtImpl(this.rpc, workspaceExt);
|
|
62
63
|
const terminalService = new TerminalServiceExtImpl(this.rpc);
|
|
63
64
|
const secretsExt = new SecretsExtImpl(this.rpc);
|
|
64
|
-
|
|
65
|
+
const localizationExt = new LocalizationExtImpl(this.rpc);
|
|
66
|
+
this.pluginManager = this.createPluginManager(envExt, terminalService, storageProxy, preferenceRegistryExt, webviewExt, secretsExt, localizationExt, this.rpc);
|
|
65
67
|
this.rpc.set(MAIN_RPC_CONTEXT.HOSTED_PLUGIN_MANAGER_EXT, this.pluginManager);
|
|
66
68
|
this.rpc.set(MAIN_RPC_CONTEXT.EDITORS_AND_DOCUMENTS_EXT, editorsAndDocumentsExt);
|
|
67
69
|
this.rpc.set(MAIN_RPC_CONTEXT.WORKSPACE_EXT, workspaceExt);
|
|
@@ -80,7 +82,8 @@ export class PluginHostRPC {
|
|
|
80
82
|
workspaceExt,
|
|
81
83
|
messageRegistryExt,
|
|
82
84
|
clipboardExt,
|
|
83
|
-
webviewExt
|
|
85
|
+
webviewExt,
|
|
86
|
+
localizationExt
|
|
84
87
|
);
|
|
85
88
|
connectProxyResolver(workspaceExt, preferenceRegistryExt);
|
|
86
89
|
}
|
|
@@ -102,7 +105,7 @@ export class PluginHostRPC {
|
|
|
102
105
|
|
|
103
106
|
createPluginManager(
|
|
104
107
|
envExt: EnvExtImpl, terminalService: TerminalServiceExtImpl, storageProxy: KeyValueStorageProxy,
|
|
105
|
-
preferencesManager: PreferenceRegistryExtImpl, webview: WebviewsExtImpl, secretsExt: SecretsExtImpl,
|
|
108
|
+
preferencesManager: PreferenceRegistryExtImpl, webview: WebviewsExtImpl, secretsExt: SecretsExtImpl, localization: LocalizationExt,
|
|
106
109
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
107
110
|
rpc: any
|
|
108
111
|
): PluginManagerExtImpl {
|
|
@@ -239,7 +242,7 @@ export class PluginHostRPC {
|
|
|
239
242
|
`Path ${extensionTestsPath} does not point to a valid extension test runner.`
|
|
240
243
|
);
|
|
241
244
|
} : undefined
|
|
242
|
-
}, envExt, terminalService, storageProxy, secretsExt, preferencesManager, webview, rpc);
|
|
245
|
+
}, envExt, terminalService, storageProxy, secretsExt, preferencesManager, webview, localization, rpc);
|
|
243
246
|
return pluginManager;
|
|
244
247
|
}
|
|
245
248
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2023 TypeFox and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { injectable } from '@theia/core/shared/inversify';
|
|
18
|
+
import { LanguagePackBundle, LanguagePackService } from '../../common/language-pack-service';
|
|
19
|
+
|
|
20
|
+
@injectable()
|
|
21
|
+
export class PluginLanguagePackService implements LanguagePackService {
|
|
22
|
+
|
|
23
|
+
protected readonly storage = new Map<string, Map<string, LanguagePackBundle>>();
|
|
24
|
+
|
|
25
|
+
storeBundle(pluginId: string, locale: string, bundle: LanguagePackBundle): void {
|
|
26
|
+
if (!this.storage.has(pluginId)) {
|
|
27
|
+
this.storage.set(pluginId, new Map());
|
|
28
|
+
}
|
|
29
|
+
this.storage.get(pluginId)!.set(locale, bundle);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
deleteBundle(pluginId: string, locale?: string): void {
|
|
33
|
+
if (locale) {
|
|
34
|
+
this.storage.get(pluginId)?.delete(locale);
|
|
35
|
+
} else {
|
|
36
|
+
this.storage.delete(pluginId);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async getBundle(pluginId: string, locale: string): Promise<LanguagePackBundle | undefined> {
|
|
41
|
+
return this.storage.get(pluginId)?.get(locale);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -116,6 +116,7 @@ export class TheiaPluginScanner implements PluginScanner {
|
|
|
116
116
|
version: plugin.version,
|
|
117
117
|
displayName: plugin.displayName,
|
|
118
118
|
description: plugin.description,
|
|
119
|
+
l10n: plugin.l10n,
|
|
119
120
|
engine: {
|
|
120
121
|
type: this._apiType,
|
|
121
122
|
version: plugin.engines[this._apiType]
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
Comment,
|
|
19
19
|
CommentMode,
|
|
20
20
|
CommentThread,
|
|
21
|
+
CommentThreadState,
|
|
21
22
|
CommentThreadCollapsibleState
|
|
22
23
|
} from '../../../common/plugin-api-rpc-model';
|
|
23
24
|
import { CommentGlyphWidget } from './comment-glyph-widget';
|
|
@@ -97,6 +98,9 @@ export class CommentThreadWidget extends BaseWidget {
|
|
|
97
98
|
commentForm.update();
|
|
98
99
|
}
|
|
99
100
|
}));
|
|
101
|
+
this.toDispose.push(this._commentThread.onDidChangeState(_state => {
|
|
102
|
+
this.update();
|
|
103
|
+
}));
|
|
100
104
|
this.contextMenu = this.menus.getMenu(COMMENT_THREAD_CONTEXT);
|
|
101
105
|
this.contextMenu.children.map(node => node instanceof ActionMenuNode && node.when).forEach(exp => {
|
|
102
106
|
if (typeof exp === 'string') {
|
|
@@ -231,7 +235,8 @@ export class CommentThreadWidget extends BaseWidget {
|
|
|
231
235
|
if (this._commentThread.comments && this._commentThread.comments.length) {
|
|
232
236
|
const onlyUnique = (value: Comment, index: number, self: Comment[]) => self.indexOf(value) === index;
|
|
233
237
|
const participantsList = this._commentThread.comments.filter(onlyUnique).map(comment => `@${comment.userName}`).join(', ');
|
|
234
|
-
|
|
238
|
+
const resolutionState = this._commentThread.state === CommentThreadState.Resolved ? '(Resolved)' : '(Unresolved)';
|
|
239
|
+
label = `Participants: ${participantsList} ${resolutionState}`;
|
|
235
240
|
} else {
|
|
236
241
|
label = 'Start discussion';
|
|
237
242
|
}
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
CommentThreadChangedEvent
|
|
24
24
|
} from '../../../common/plugin-api-rpc-model';
|
|
25
25
|
import { Event, Emitter } from '@theia/core/lib/common/event';
|
|
26
|
-
import { CommentThreadCollapsibleState } from '../../../plugin/types-impl';
|
|
26
|
+
import { CommentThreadCollapsibleState, CommentThreadState } from '../../../plugin/types-impl';
|
|
27
27
|
import {
|
|
28
28
|
CommentProviderFeatures,
|
|
29
29
|
CommentsExt,
|
|
@@ -124,6 +124,21 @@ export class CommentThreadImpl implements CommentThread, Disposable {
|
|
|
124
124
|
private readonly onDidChangeCollapsibleStateEmitter = new Emitter<CommentThreadCollapsibleState | undefined>();
|
|
125
125
|
readonly onDidChangeCollapsibleState = this.onDidChangeCollapsibleStateEmitter.event;
|
|
126
126
|
|
|
127
|
+
private _state: CommentThreadState | undefined;
|
|
128
|
+
get state(): CommentThreadState | undefined {
|
|
129
|
+
return this._state;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
set state(newState: CommentThreadState | undefined) {
|
|
133
|
+
if (this._state !== newState) {
|
|
134
|
+
this._state = newState;
|
|
135
|
+
this.onDidChangeStateEmitter.fire(this._state);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
private readonly onDidChangeStateEmitter = new Emitter<CommentThreadState | undefined>();
|
|
140
|
+
readonly onDidChangeState = this.onDidChangeStateEmitter.event;
|
|
141
|
+
|
|
127
142
|
private readonly onDidChangeCanReplyEmitter = new Emitter<boolean>();
|
|
128
143
|
readonly onDidChangeCanReply = this.onDidChangeCanReplyEmitter.event;
|
|
129
144
|
|
|
@@ -163,12 +178,14 @@ export class CommentThreadImpl implements CommentThread, Disposable {
|
|
|
163
178
|
if (modified('contextValue')) { this._contextValue = changes.contextValue; }
|
|
164
179
|
if (modified('comments')) { this._comments = changes.comments; }
|
|
165
180
|
if (modified('collapseState')) { this._collapsibleState = changes.collapseState; }
|
|
181
|
+
if (modified('state')) { this._state = changes.state; }
|
|
166
182
|
if (modified('canReply')) { this._canReply = changes.canReply!; }
|
|
167
183
|
}
|
|
168
184
|
|
|
169
185
|
dispose(): void {
|
|
170
186
|
this._isDisposed = true;
|
|
171
187
|
this.onDidChangeCollapsibleStateEmitter.dispose();
|
|
188
|
+
this.onDidChangeStateEmitter.dispose();
|
|
172
189
|
this.onDidChangeCommentsEmitter.dispose();
|
|
173
190
|
this.onDidChangeInputEmitter.dispose();
|
|
174
191
|
this.onDidChangeLabelEmitter.dispose();
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// *****************************************************************************
|
|
2
|
+
// Copyright (C) 2023 TypeFox and others.
|
|
3
|
+
//
|
|
4
|
+
// This program and the accompanying materials are made available under the
|
|
5
|
+
// terms of the Eclipse Public License v. 2.0 which is available at
|
|
6
|
+
// http://www.eclipse.org/legal/epl-2.0.
|
|
7
|
+
//
|
|
8
|
+
// This Source Code may also be made available under the following Secondary
|
|
9
|
+
// Licenses when the conditions for such availability set forth in the Eclipse
|
|
10
|
+
// Public License v. 2.0 are satisfied: GNU General Public License, version 2
|
|
11
|
+
// with the GNU Classpath Exception which is available at
|
|
12
|
+
// https://www.gnu.org/software/classpath/license.html.
|
|
13
|
+
//
|
|
14
|
+
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
|
|
15
|
+
// *****************************************************************************
|
|
16
|
+
|
|
17
|
+
import { nls } from '@theia/core';
|
|
18
|
+
import { interfaces } from '@theia/core/shared/inversify';
|
|
19
|
+
import { LocalizationMain } from '../../common/plugin-api-rpc';
|
|
20
|
+
import { LanguagePackBundle, LanguagePackService } from '../../common/language-pack-service';
|
|
21
|
+
|
|
22
|
+
export class LocalizationMainImpl implements LocalizationMain {
|
|
23
|
+
|
|
24
|
+
private readonly languagePackService: LanguagePackService;
|
|
25
|
+
|
|
26
|
+
constructor(container: interfaces.Container) {
|
|
27
|
+
this.languagePackService = container.get(LanguagePackService);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async $fetchBundle(id: string): Promise<LanguagePackBundle | undefined> {
|
|
31
|
+
const bundle = await this.languagePackService.getBundle(id, nls.locale ?? nls.defaultLocale);
|
|
32
|
+
return bundle;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -59,6 +59,7 @@ import { MonacoLanguages } from '@theia/monaco/lib/browser/monaco-languages';
|
|
|
59
59
|
import { UntitledResourceResolver } from '@theia/core/lib/common/resource';
|
|
60
60
|
import { ThemeService } from '@theia/core/lib/browser/theming';
|
|
61
61
|
import { TabsMainImpl } from './tabs/tabs-main';
|
|
62
|
+
import { LocalizationMainImpl } from './localization-main';
|
|
62
63
|
|
|
63
64
|
export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container): void {
|
|
64
65
|
const authenticationMain = new AuthenticationMainImpl(rpc, container);
|
|
@@ -184,4 +185,7 @@ export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container
|
|
|
184
185
|
|
|
185
186
|
const tabsMain = new TabsMainImpl(rpc, container);
|
|
186
187
|
rpc.set(PLUGIN_RPC_CONTEXT.TABS_MAIN, tabsMain);
|
|
188
|
+
|
|
189
|
+
const localizationMain = new LocalizationMainImpl(container);
|
|
190
|
+
rpc.set(PLUGIN_RPC_CONTEXT.LOCALIZATION_MAIN, localizationMain);
|
|
187
191
|
}
|
|
@@ -83,6 +83,7 @@ import './theme-icon-override';
|
|
|
83
83
|
import { PluginTerminalRegistry } from './plugin-terminal-registry';
|
|
84
84
|
import { DnDFileContentStore } from './view/dnd-file-content-store';
|
|
85
85
|
import { WebviewContextKeys } from './webview/webview-context-keys';
|
|
86
|
+
import { LanguagePackService, languagePackServicePath } from '../../common/language-pack-service';
|
|
86
87
|
|
|
87
88
|
export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|
88
89
|
|
|
@@ -249,4 +250,9 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
|
|
|
249
250
|
rebind(AuthenticationService).toService(PluginAuthenticationServiceImpl);
|
|
250
251
|
|
|
251
252
|
bind(PluginTerminalRegistry).toSelf().inSingletonScope();
|
|
253
|
+
|
|
254
|
+
bind(LanguagePackService).toDynamicValue(ctx => {
|
|
255
|
+
const provider = ctx.container.get(WebSocketConnectionProvider);
|
|
256
|
+
return provider.createProxy<LanguagePackService>(languagePackServicePath);
|
|
257
|
+
}).inSingletonScope();
|
|
252
258
|
});
|