1
1
Add display language support
2
2
3
- We can remove this once upstream supports all language packs.
4
-
5
- 1. Proxies language packs to the service on the backend.
6
- 2. NLS configuration is embedded into the HTML for the browser to pick up. This
7
- code to generate this configuration is copied from the native portion.
8
- 3. Remove configuredLocale since we have our own thing.
9
- 4. Move the argv.json file to the server instead of in-browser storage. This is
10
- where the current locale is stored and currently the server needs to be able
11
- to read it.
12
- 5. Add the locale flag.
13
- 6. Remove the redundant locale verification. It does the same as the existing
14
- one but is worse because it does not handle non-existent or empty files.
15
- 7. Replace some caching and Node requires because code-server does not restart
16
- when changing the language unlike native Code.
17
- 8. Make language extensions installable like normal rather than using the
18
- special set/clear language actions.
3
+ VS Code web appears to implement language support by setting a cookie and
4
+ downloading language packs from a URL configured in the product.json. This patch
5
+ supports language pack extensions and uses files on the remote to set the
6
+ language instead, so it works like the desktop version.
19
7
20
8
Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
21
9
===================================================================
22
10
--- code-server.orig/lib/vscode/src/vs/server/node/serverServices.ts
23
11
+++ code-server/lib/vscode/src/vs/server/node/serverServices.ts
24
- @@ -11 ,7 +11 ,7 @@ import * as path from 'vs/base/common/pa
12
+ @@ -12 ,7 +12 ,7 @@ import * as path from 'vs/base/common/pa
25
13
import { IURITransformer } from 'vs/base/common/uriIpc';
26
14
import { getMachineId, getSqmMachineId, getdevDeviceId } from 'vs/base/node/id';
27
15
import { Promises } from 'vs/base/node/pfs';
@@ -30,7 +18,7 @@ Index: code-server/lib/vscode/src/vs/server/node/serverServices.ts
30
18
import { ProtocolConstants } from 'vs/base/parts/ipc/common/ipc.net';
31
19
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
32
20
import { ConfigurationService } from 'vs/platform/configuration/common/configurationService';
33
- @@ -238 ,6 +238 ,9 @@ export async function setupServerService
21
+ @@ -239 ,6 +239 ,9 @@ export async function setupServerService
34
22
const channel = new ExtensionManagementChannel(extensionManagementService, (ctx: RemoteAgentConnectionContext) => getUriTransformer(ctx.remoteAuthority));
35
23
socketServer.registerChannel('extensions', channel);
36
24
@@ -44,36 +32,16 @@ Index: code-server/lib/vscode/src/vs/base/common/platform.ts
44
32
===================================================================
45
33
--- code-server.orig/lib/vscode/src/vs/base/common/platform.ts
46
34
+++ code-server/lib/vscode/src/vs/base/common/platform.ts
47
- @@ -2,8 +2,6 @@
48
- * Copyright (c) Microsoft Corporation. All rights reserved.
49
- * Licensed under the MIT License. See License.txt in the project root for license information.
50
- *--------------------------------------------------------------------------------------------*/
51
- - import * as nls from 'vs/nls';
52
- -
53
- export const LANGUAGE_DEFAULT = 'en';
54
-
55
- let _isWindows = false;
56
- @@ -112,17 +110,21 @@ else if (typeof navigator === 'object' &
57
- _isMobile = _userAgent?.indexOf('Mobi') >= 0;
58
- _isWeb = true;
59
-
60
- - const configuredLocale = nls.getConfiguredDefaultLocale(
61
- - // This call _must_ be done in the file that calls `nls.getConfiguredDefaultLocale`
62
- - // to ensure that the NLS AMD Loader plugin has been loaded and configured.
63
- - // This is because the loader plugin decides what the default locale is based on
64
- - // how it's able to resolve the strings.
65
- - nls.localize({ key: 'ensureLoaderPluginIsLoaded', comment: ['{Locked}'] }, '_')
66
- - );
67
- -
68
- - _locale = configuredLocale || LANGUAGE_DEFAULT;
69
- + _locale = LANGUAGE_DEFAULT;
70
- _language = _locale;
71
- _platformLocale = navigator.language;
72
- + const el = typeof document !== 'undefined' && document.getElementById('vscode-remote-nls-configuration');
73
- + const rawNlsConfig = el && el.getAttribute('data-settings');
35
+ @@ -107,6 +107,19 @@ else if (typeof navigator === 'object' &
36
+ _language = globalThis._VSCODE_NLS_LANGUAGE || LANGUAGE_DEFAULT;
37
+ _locale = navigator.language.toLowerCase();
38
+ _platformLocale = _locale;
39
+ +
40
+ + const el = document?.getElementById('vscode-remote-nls-configuration');
41
+ + const rawNlsConfig = el?.getAttribute('data-settings');
74
42
+ if (rawNlsConfig) {
75
43
+ try {
76
- + const nlsConfig: NLSConfig = JSON.parse(rawNlsConfig);
44
+ + const nlsConfig: nls.INLSConfiguration = JSON.parse(rawNlsConfig);
77
45
+ const resolved = nlsConfig.availableLanguages['*'];
78
46
+ _locale = nlsConfig.locale;
79
47
+ _platformLocale = nlsConfig.osLocale;
@@ -98,19 +66,11 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html
98
66
<!-- Workbench Icon/Manifest/CSS -->
99
67
<link rel="icon" href="{{BASE}}/_static/src/browser/media/favicon-dark-support.svg" />
100
68
<link rel="alternate icon" href="{{BASE}}/_static/src/browser/media/favicon.ico" type="image/x-icon" />
101
- @@ -48,15 +51,27 @@
102
- // Normalize locale to lowercase because translationServiceUrl is case-sensitive.
103
- // ref: https://github.com/microsoft/vscode/issues/187795
104
- const locale = localStorage.getItem('vscode.nls.locale') || navigator.language.toLowerCase();
105
- - if (!locale.startsWith('en')) {
106
- - nlsConfig['vs/nls'] = {
107
- - availableLanguages: {
108
- - '*': locale
109
- - },
110
- - translationServiceUrl: '{{WORKBENCH_NLS_BASE_URL}}'
111
- - };
112
- - }
69
+ @@ -45,6 +48,28 @@
70
+ self.webPackagePaths[key] = `${baseUrl}/node_modules/${key}/${self.webPackagePaths[key]}`;
71
+ });
113
72
73
+ + const nlsConfig = {};
114
74
+ try {
115
75
+ nlsConfig['vs/nls'] = JSON.parse(document.getElementById("vscode-remote-nls-configuration").getAttribute("data-settings"))
116
76
+ if (nlsConfig['vs/nls']._resolvedLanguagePackCoreLocation) {
@@ -131,9 +91,20 @@ Index: code-server/lib/vscode/src/vs/code/browser/workbench/workbench.html
131
91
+ }
132
92
+ }
133
93
+ } catch (error) { /* Probably fine. */ }
94
+ +
95
+ // AMD Loader
134
96
require.config({
135
97
baseUrl: `${baseUrl}/out`,
136
- recordStats: true,
98
+ @@ -57,7 +82,8 @@
99
+ throw new Error(`Invalid script url: ${value}`)
100
+ }
101
+ }),
102
+ - paths: self.webPackagePaths
103
+ + paths: self.webPackagePaths,
104
+ + ...nlsConfig,
105
+ });
106
+ </script>
107
+ <script>
137
108
Index: code-server/lib/vscode/src/vs/platform/environment/common/environmentService.ts
138
109
===================================================================
139
110
--- code-server.orig/lib/vscode/src/vs/platform/environment/common/environmentService.ts
@@ -151,22 +122,17 @@ Index: code-server/lib/vscode/src/vs/server/node/remoteLanguagePacks.ts
151
122
===================================================================
152
123
--- code-server.orig/lib/vscode/src/vs/server/node/remoteLanguagePacks.ts
153
124
+++ code-server/lib/vscode/src/vs/server/node/remoteLanguagePacks.ts
154
- @@ -32,6 +32,12 @@ export function getNLSConfiguration(lang
155
- if (InternalNLSConfiguration.is(value)) {
156
- value._languagePackSupport = true;
157
- }
158
- + // If the configuration has no results keep trying since code-server
159
- + // doesn't restart when a language is installed so this result would
160
- + // persist (the plugin might not be installed yet for example).
161
- + if (value.locale !== 'en' && value.locale !== 'en-us' && Object.keys(value.availableLanguages).length === 0) {
162
- + _cache.delete(key);
163
- + }
164
- return value;
165
- });
166
- _cache.set(key, result);
167
- @@ -46,3 +52,43 @@ export namespace InternalNLSConfiguratio
168
- return candidate && typeof candidate._languagePackId === 'string';
169
- }
125
+ @@ -3,6 +3,7 @@
126
+ * Licensed under the MIT License. See License.txt in the project root for license information.
127
+ *--------------------------------------------------------------------------------------------*/
128
+
129
+ + import { promises as fs } from 'fs';
130
+ import { FileAccess } from 'vs/base/common/network';
131
+ import { join } from 'vs/base/common/path';
132
+ import type { INLSConfiguration } from 'vs/nls';
133
+ @@ -37,3 +38,43 @@ export async function getNLSConfiguratio
134
+
135
+ return result;
170
136
}
171
137
+
172
138
+ /**
@@ -175,7 +141,7 @@ Index: code-server/lib/vscode/src/vs/server/node/remoteLanguagePacks.ts
175
141
+
176
142
+ export const getLocaleFromConfig = async (argvResource: string): Promise<string> => {
177
143
+ try {
178
- + const content = stripComments(await fs.promises. readFile(argvResource, 'utf8'));
144
+ + const content = stripComments(await fs.readFile(argvResource, 'utf8'));
179
145
+ return JSON.parse(content).locale;
180
146
+ } catch (error) {
181
147
+ if (error.code !== "ENOENT") {
@@ -212,25 +178,26 @@ Index: code-server/lib/vscode/src/vs/server/node/webClientServer.ts
212
178
===================================================================
213
179
--- code-server.orig/lib/vscode/src/vs/server/node/webClientServer.ts
214
180
+++ code-server/lib/vscode/src/vs/server/node/webClientServer.ts
215
- @@ -27 ,6 +27 ,7 @@ import { URI } from 'vs/base/common/uri'
181
+ @@ -26 ,6 +26 ,7 @@ import { URI } from 'vs/base/common/uri'
216
182
import { streamToBuffer } from 'vs/base/common/buffer';
217
183
import { IProductConfiguration } from 'vs/base/common/product';
218
184
import { isString } from 'vs/base/common/types';
219
185
+ import { getLocaleFromConfig, getNLSConfiguration } from 'vs/server/node/remoteLanguagePacks';
220
186
import { CharCode } from 'vs/base/common/charCode';
221
187
import { IExtensionManifest } from 'vs/platform/extensions/common/extensions';
222
188
223
- @@ -348,6 +349,8 @@ export class WebClientServer {
224
- callbackRoute: this._callbackRoute
189
+ @@ -349,7 +350,8 @@ export class WebClientServer {
225
190
};
226
191
227
- + const locale = this._environmentService.args.locale || await getLocaleFromConfig(this._environmentService.argvResource.fsPath);
192
+ const cookies = cookie.parse(req.headers.cookie || '');
193
+ - const locale = cookies['vscode.nls.locale'] || req.headers['accept-language']?.split(',')[0]?.toLowerCase() || 'en';
194
+ + const locale = this._environmentService.args.locale || await getLocaleFromConfig(this._environmentService.argvResource.fsPath) || cookies['vscode.nls.locale'] || req.headers['accept-language']?.split(',')[0]?.toLowerCase() || 'en';
228
195
+ const nlsConfiguration = await getNLSConfiguration(locale, this._environmentService.userDataPath)
229
- const nlsBaseUrl = this._productService.extensionsGallery?.nlsBaseUrl ;
230
- const values: { [key: string]: string } = {
231
- WORKBENCH_WEB_CONFIGURATION: asJSON(workbenchWebConfiguration),
232
- @@ -356 ,6 +359 ,7 @@ export class WebClientServer {
233
- WORKBENCH_NLS_BASE_URL: vscodeBase + (nlsBaseUrl ? `${nlsBaseUrl }${!nlsBaseUrl.endsWith('/') ? '/' : ''}${ this._productService.commit}/${this._productService.version}/` : '') ,
196
+ let WORKBENCH_NLS_BASE_URL: string | undefined ;
197
+ let WORKBENCH_NLS_URL: string;
198
+ if (!locale.startsWith('en') && this._productService.nlsCoreBaseUrl) {
199
+ @@ -367 ,6 +369 ,7 @@ export class WebClientServer {
200
+ WORKBENCH_NLS_FALLBACK_URL: `${vscodeBase }${this._staticRoute}/out/nls.messages.js` ,
234
201
BASE: base,
235
202
VS_BASE: vscodeBase,
236
203
+ NLS_CONFIGURATION: asJSON(nlsConfiguration),
@@ -241,18 +208,18 @@ Index: code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
241
208
===================================================================
242
209
--- code-server.orig/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
243
210
+++ code-server/lib/vscode/src/vs/server/node/serverEnvironmentService.ts
244
- @@ -18,6 +18,7 @@ export const serverOptions: OptionDescri
245
- 'auth': { type: 'string' },
211
+ @@ -19,6 +19,7 @@ export const serverOptions: OptionDescri
246
212
'disable-file-downloads': { type: 'boolean' },
247
213
'disable-file-uploads': { type: 'boolean' },
214
+ 'disable-getting-started-override': { type: 'boolean' },
248
215
+ 'locale': { type: 'string' },
249
216
250
217
/* ----- server setup ----- */
251
218
252
- @@ -103,6 +104,7 @@ export interface ServerParsedArgs {
253
- 'auth'?: string;
219
+ @@ -105,6 +106,7 @@ export interface ServerParsedArgs {
254
220
'disable-file-downloads'?: boolean;
255
221
'disable-file-uploads'?: boolean;
222
+ 'disable-getting-started-override'?: boolean,
256
223
+ 'locale'?: string
257
224
258
225
/* ----- server setup ----- */
@@ -367,7 +334,7 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
367
334
}
368
335
369
336
// Prefers to run on UI
370
- @@ -1928 ,17 +1925 ,6 @@ export class SetLanguageAction extends E
337
+ @@ -1951 ,17 +1948 ,6 @@ export class SetLanguageAction extends E
371
338
update(): void {
372
339
this.enabled = false;
373
340
this.class = SetLanguageAction.DisabledClass;
@@ -385,15 +352,15 @@ Index: code-server/lib/vscode/src/vs/workbench/contrib/extensions/browser/extens
385
352
}
386
353
387
354
override async run(): Promise<any> {
388
- @@ -1955 ,7 +1941 ,6 @@ export class ClearLanguageAction extends
389
- private static readonly DisabledClass = `${ClearLanguageAction .EnabledClass} disabled`;
355
+ @@ -1978 ,7 +1964 ,6 @@ export class ClearLanguageAction extends
356
+ private static readonly DisabledClass = `${this .EnabledClass} disabled`;
390
357
391
358
constructor(
392
359
- @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService,
393
360
@ILocaleService private readonly localeService: ILocaleService,
394
361
) {
395
362
super(ClearLanguageAction.ID, ClearLanguageAction.TITLE.value, ClearLanguageAction.DisabledClass, false);
396
- @@ -1965 ,17 +1950 ,6 @@ export class ClearLanguageAction extends
363
+ @@ -1988 ,17 +1973 ,6 @@ export class ClearLanguageAction extends
397
364
update(): void {
398
365
this.enabled = false;
399
366
this.class = ClearLanguageAction.DisabledClass;
0 commit comments