Skip to content

Commit

Permalink
Ensuring locale is set to the OS locale and language is set to the Ap…
Browse files Browse the repository at this point in the history
…plication Language

Ref #164397
  • Loading branch information
TylerLeonhardt committed Feb 18, 2023
1 parent 0b89e36 commit 61f0d4c
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 98 deletions.
71 changes: 34 additions & 37 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,27 @@ registerListeners();
let nlsConfigurationPromise = undefined;

const metaDataFile = path.join(__dirname, 'nls.metadata.json');
const locale = getUserDefinedLocale(argvConfig);
if (locale) {
const language = getUserDefinedLocale(argvConfig);
/**
* @type {string | undefined}
**/
let osLocale = undefined;
// This if statement can be simplified once
// VS Code moves to Electron 22.
// Ref https://github.com/microsoft/vscode/issues/159813
// and https://github.com/electron/electron/pull/36035
if ('getPreferredSystemLanguages' in app
&& typeof app.getPreferredSystemLanguages === 'function'
&& app.getPreferredSystemLanguages().length) {
// Use the most preferred OS language for language recommendation.
osLocale = app.getPreferredSystemLanguages()[0];
if (osLocale) {
osLocale = processZhLocale(osLocale.toLowerCase());
}
}
if (language && osLocale) {
const { getNLSConfiguration } = require('./vs/base/node/languagePacks');
nlsConfigurationPromise = getNLSConfiguration(product.commit, userDataPath, metaDataFile, locale);
nlsConfigurationPromise = getNLSConfiguration(product.commit, userDataPath, metaDataFile, osLocale, language);
}

// Pass in the locale to Electron so that the
Expand All @@ -108,7 +125,7 @@ if (locale) {
// In that case, use `en` as the Electron locale.

if (process.platform === 'win32' || process.platform === 'linux') {
const electronLocale = (!locale || locale === 'qps-ploc') ? 'en' : locale;
const electronLocale = (!language || language === 'qps-ploc') ? 'en' : language;
app.commandLine.appendSwitch('lang', electronLocale);
}

Expand Down Expand Up @@ -554,6 +571,10 @@ async function mkdirpIgnoreError(dir) {

//#region NLS Support

/**
* @param {string} appLocale
* @returns string
*/
function processZhLocale(appLocale) {
if (appLocale.startsWith('zh')) {
const region = appLocale.split('-')[1];
Expand Down Expand Up @@ -585,39 +606,15 @@ async function resolveNlsConfiguration() {
// If that fails we fall back to English.
let nlsConfiguration = nlsConfigurationPromise ? await nlsConfigurationPromise : undefined;
if (!nlsConfiguration) {

// Try to use the app locale. Please note that the app locale is only
// valid after we have received the app ready event. This is why the
// code is here.

/**
* @type string
*/
let appLocale = app.getLocale();

// This if statement can be simplified once
// VS Code moves to Electron 22.
// Ref https://github.com/microsoft/vscode/issues/159813
// and https://github.com/electron/electron/pull/36035
if ((process.platform === 'win32' || process.platform === 'linux')
&& 'getPreferredSystemLanguages' in app
&& typeof app.getPreferredSystemLanguages === 'function'
&& app.getPreferredSystemLanguages().length) {
// Use the most preferred OS language for language recommendation.
appLocale = app.getPreferredSystemLanguages()[0];
}

if (!appLocale) {
nlsConfiguration = { locale: 'en', availableLanguages: {} };
} else {
// See above the comment about the loader and case sensitiveness
appLocale = processZhLocale(appLocale.toLowerCase());

const { getNLSConfiguration } = require('./vs/base/node/languagePacks');
nlsConfiguration = await getNLSConfiguration(product.commit, userDataPath, metaDataFile, appLocale);
if (!nlsConfiguration) {
nlsConfiguration = { locale: appLocale, availableLanguages: {} };
}
// fallback to using app.getLocale() so that we have something for the locale.
// This can be removed after the move to Electron 22. Please note that getLocale() is only
// valid after we have received the app ready event. This is why the code is here.
osLocale ??= processZhLocale(app.getLocale().toLowerCase());

const { getNLSConfiguration } = require('./vs/base/node/languagePacks');
nlsConfiguration = await getNLSConfiguration(product.commit, userDataPath, metaDataFile, osLocale, language);
if (!nlsConfiguration) {
nlsConfiguration = { locale: osLocale, availableLanguages: {} };
}
} else {
// We received a valid nlsConfig from a user defined locale
Expand Down
7 changes: 3 additions & 4 deletions src/vs/base/common/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ export const platform = _platform;
export const userAgent = _userAgent;

/**
* The language used for the user interface. The format of
* the string is all lower case (e.g. zh-tw for Traditional
* The language used for the user interface. or the locale specified by --locale
* The format of the string is all lower case (e.g. zh-tw for Traditional
* Chinese)
*/
export const language = _language;
Expand All @@ -200,8 +200,7 @@ export namespace Language {
}

/**
* The OS locale or the locale specified by --locale. The format of
* the string is all lower case (e.g. zh-tw for Traditional
* The OS locale. The format of the string is all lower case (e.g. zh-tw for Traditional
* Chinese). The UI is not necessarily shown in the provided locale.
*/
export const locale = _locale;
Expand Down
2 changes: 1 addition & 1 deletion src/vs/base/node/languagePacks.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ export interface InternalNLSConfiguration extends NLSConfiguration {
_languagePackSupport?: boolean;
}

export function getNLSConfiguration(commit: string | undefined, userDataPath: string, metaDataFile: string, locale: string): Promise<NLSConfiguration>;
export function getNLSConfiguration(commit: string | undefined, userDataPath: string, metaDataFile: string, locale: string, language: string | undefined): Promise<NLSConfiguration>;
77 changes: 22 additions & 55 deletions src/vs/base/node/languagePacks.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,43 +80,16 @@
return undefined;
}

/**
* @param {object} config
* @param {string | undefined} locale
*/
function resolveLanguagePackLocale(config, locale) {
try {
while (locale) {
if (config[locale]) {
return locale;
} else {
const index = locale.lastIndexOf('-');
if (index > 0) {
locale = locale.substring(0, index);
} else {
return undefined;
}
}
}
} catch (err) {
console.error('Resolving language pack configuration failed.', err);
}
return undefined;
}

/**
* @param {string | undefined} commit
* @param {string} userDataPath
* @param {string} metaDataFile
* @param {string | undefined} locale
* @param {string} locale
* @param {string | undefined} language
*/
function getNLSConfiguration(commit, userDataPath, metaDataFile, locale) {
if (locale === 'pseudo') {
return Promise.resolve({ locale: locale, availableLanguages: {}, pseudo: true });
}

function getNLSConfiguration(commit, userDataPath, metaDataFile, locale, language) {
if (process.env['VSCODE_DEV']) {
return Promise.resolve({ locale: locale, availableLanguages: {} });
return Promise.resolve({ locale, availableLanguages: {} });
}

// We have a built version so we have extracted nls file. Try to find
Expand All @@ -125,53 +98,47 @@
// Check if we have an English or English US locale. If so fall to default since that is our
// English translation (we don't ship *.nls.en.json files)
if (locale && (locale === 'en' || locale === 'en-us')) {
return Promise.resolve({ locale: locale, availableLanguages: {} });
return Promise.resolve({ locale, availableLanguages: {} });
}

const initialLocale = locale;

perf.mark('code/willGenerateNls');

const defaultResult = function (locale) {
perf.mark('code/didGenerateNls');
return Promise.resolve({ locale: locale, availableLanguages: {} });
return Promise.resolve({ locale, availableLanguages: {} });
};
try {
if (!commit) {
return defaultResult(initialLocale);
return defaultResult(locale);
}
return getLanguagePackConfigurations(userDataPath).then(configs => {
if (!configs) {
return defaultResult(initialLocale);
}
locale = resolveLanguagePackLocale(configs, locale);
if (!locale) {
return defaultResult(initialLocale);
return defaultResult(locale);
}
const packConfig = configs[locale];
let mainPack;
if (!packConfig || typeof packConfig.hash !== 'string' || !packConfig.translations || typeof (mainPack = packConfig.translations['vscode']) !== 'string') {
return defaultResult(initialLocale);
return defaultResult(locale);
}
return exists(mainPack).then(fileExists => {
if (!fileExists) {
return defaultResult(initialLocale);
return defaultResult(locale);
}
const packId = packConfig.hash + '.' + locale;
const cacheRoot = path.join(userDataPath, 'clp', packId);
const _languagePackId = packConfig.hash + '.' + locale;
const cacheRoot = path.join(userDataPath, 'clp', _languagePackId);
const coreLocation = path.join(cacheRoot, commit);
const translationsConfigFile = path.join(cacheRoot, 'tcf.json');
const corruptedFile = path.join(cacheRoot, 'corrupted.info');
const _translationsConfigFile = path.join(cacheRoot, 'tcf.json');
const _corruptedFile = path.join(cacheRoot, 'corrupted.info');
const result = {
locale: initialLocale,
availableLanguages: { '*': locale },
_languagePackId: packId,
_translationsConfigFile: translationsConfigFile,
locale,
availableLanguages: { '*': language },
_languagePackId,
_translationsConfigFile,
_cacheRoot: cacheRoot,
_resolvedLanguagePackCoreLocation: coreLocation,
_corruptedFile: corruptedFile
_corruptedFile,
_resolvedLanguagePackCoreLocation: coreLocation
};
return exists(corruptedFile).then(corrupted => {
return exists(_corruptedFile).then(corrupted => {
// The nls cache directory is corrupted.
let toDelete;
if (corrupted) {
Expand Down Expand Up @@ -220,7 +187,7 @@
}
writes.push(writeFile(path.join(coreLocation, bundle.replace(/\//g, '!') + '.nls.json'), JSON.stringify(target)));
}
writes.push(writeFile(translationsConfigFile, JSON.stringify(packConfig.translations)));
writes.push(writeFile(_translationsConfigFile, JSON.stringify(packConfig.translations)));
return Promise.all(writes);
}).then(() => {
perf.mark('code/didGenerateNls');
Expand Down
4 changes: 3 additions & 1 deletion src/vs/server/node/remoteLanguagePacks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ export function getNLSConfiguration(language: string, userDataPath: string): Pro
const key = `${language}||${userDataPath}`;
let result = _cache.get(key);
if (!result) {
result = lp.getNLSConfiguration(product.commit, userDataPath, metaData, language).then(value => {
// For remote, we just use language for both locale and language since we don't have any use case for the locale
// on the server side.
result = lp.getNLSConfiguration(product.commit, userDataPath, metaData, language, language).then(value => {
if (InternalNLSConfiguration.is(value)) {
value._languagePackSupport = true;
}
Expand Down

0 comments on commit 61f0d4c

Please sign in to comment.