From aad46256f9d0c7d9294fc9dbcf0ea18a90a1437a Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 12 Sep 2019 16:03:25 -0700 Subject: [PATCH 1/6] Complete language variants filled in for LANG var Part of #80072 --- .../terminal/common/terminalEnvironment.ts | 46 +++++++++++++++++-- 1 file changed, 43 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index 6b9a3ec87b742..47515a593db2f 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -96,23 +96,63 @@ function _getLangEnvVariable(locale?: string) { return 'en_US.UTF-8'; } if (n === 1) { - // app.getLocale can return just a language without a variant, fill in the variant for - // supported languages as many shells expect a 2-part locale. + // The local may only contain the language, not the variant, if this is the case guess the + // variant such that it can be used as a valid $LANG variable. The language variant chosen + // is the original and/or most prominent with help from + // https://stackoverflow.com/a/2502675/1156119 + // The list of locales was generated by running `locale -a` on macOS const languageVariants: { [key: string]: string } = { + af: 'ZA', + am: 'ET', + be: 'BY', + bg: 'BG', + ca: 'ES', cs: 'CZ', + da: 'DK', + // de: 'AT', + // de: 'CH', de: 'DE', + el: 'GR', + // en: 'AU', + // en: 'CA', + // en: 'GB', + // en: 'IE', + // en: 'NZ', en: 'US', es: 'ES', + et: 'EE', + eu: 'ES', fi: 'FI', + // fr: 'BE', + // fr: 'CA', + // fr: 'CH', fr: 'FR', + he: 'IL', + hr: 'HR', hu: 'HU', + hy: 'AM', + is: 'IS', + // it: 'CH', it: 'IT', ja: 'JP', + kk: 'KZ', ko: 'KR', + lt: 'LT', + // nl: 'BE', + nl: 'NL', + no: 'NO', pl: 'PL', + pt: 'BR', + // pt: 'PT', + ro: 'RO', ru: 'RU', sk: 'SK', - zh: 'CN' + sl: 'SI', + sr: 'YU', + sv: 'SE', + tr: 'TR', + uk: 'UA', + zh: 'CN', }; if (parts[0] in languageVariants) { parts.push(languageVariants[parts[0]]); From 7694f65adb5bb015ef0e83b7396548c1ed7224bc Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 12 Sep 2019 16:04:49 -0700 Subject: [PATCH 2/6] Improve some comments Part of #80072 --- .../contrib/terminal/common/terminalEnvironment.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index 47515a593db2f..d51d317da5ea2 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -88,11 +88,11 @@ function resolveConfigurationVariables(configurationResolverService: IConfigurat return env; } -function _getLangEnvVariable(locale?: string) { +function _getLangEnvVariable(locale?: string): string { const parts = locale ? locale.split('-') : []; const n = parts.length; if (n === 0) { - // Fallback to en_US to prevent possible encoding issues. + // Fallback to en_US if the locale is unknown return 'en_US.UTF-8'; } if (n === 1) { @@ -158,7 +158,7 @@ function _getLangEnvVariable(locale?: string) { parts.push(languageVariants[parts[0]]); } } else { - // Ensure the variant is uppercase + // Ensure the variant is uppercase to be a valid $LANG parts[1] = parts[1].toUpperCase(); } return parts.join('_') + '.UTF-8'; From ebed7e9c5e69a575cdc9ae195faf22a5ed85fc21 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 12 Sep 2019 16:16:07 -0700 Subject: [PATCH 3/6] Change setLocaleVariables to detectLocale The setting is now an enum instead of boolean and defaults to auto which should provide better detection and not set in cases where it shouldn't. Fixes #80072 --- .../api/node/extHostTerminalService.ts | 2 +- .../terminal/browser/terminal.contribution.ts | 14 ++++++++++---- .../contrib/terminal/common/terminal.ts | 2 +- .../terminal/common/terminalEnvironment.ts | 18 ++++++++++++++---- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index c8198dbb93bb8..cd1a75c5406e3 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -182,7 +182,7 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService { this._variableResolver, isWorkspaceShellAllowed, pkg.version, - terminalConfig.get('setLocaleVariables', false), + terminalConfig.get('detectLocale', 'auto'), baseEnv ); diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts index db587f13986e4..9b8d567520cb3 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts @@ -194,10 +194,16 @@ configurationRegistry.registerConfiguration({ type: 'number', default: 1000 }, - 'terminal.integrated.setLocaleVariables': { - markdownDescription: nls.localize('terminal.integrated.setLocaleVariables', "Controls whether locale variables are set at startup of the terminal."), - type: 'boolean', - default: true + 'terminal.integrated.detectLocale': { + markdownDescription: nls.localize('terminal.integrated.detectLocale', "Controls whether to detect and set the `$LANG` environment variable."), + type: 'string', + enum: ['auto', 'off', 'on'], + enumDescriptions: [ + nls.localize('terminal.integrated.detectLocale.auto', "Set the `$LANG` environment variable if the existing variable does not exist or it does not end in `'.UTF-8'`."), + nls.localize('terminal.integrated.detectLocale.off', "Do not set the `$LANG` environment variable."), + nls.localize('terminal.integrated.detectLocale.on', "Always set the `$LANG` environment variable.") + ], + default: 'auto' }, 'terminal.integrated.rendererType': { type: 'string', diff --git a/src/vs/workbench/contrib/terminal/common/terminal.ts b/src/vs/workbench/contrib/terminal/common/terminal.ts index fc6b1f3faf3df..0f7bb6b9ff577 100644 --- a/src/vs/workbench/contrib/terminal/common/terminal.ts +++ b/src/vs/workbench/contrib/terminal/common/terminal.ts @@ -100,7 +100,7 @@ export interface ITerminalConfiguration { fontSize: number; letterSpacing: number; lineHeight: number; - setLocaleVariables: boolean; + detectLocale: 'auto' | 'off' | 'on'; scrollback: number; commandsToSkipShell: string[]; cwd: string; diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index d51d317da5ea2..69a3ea4c9f36f 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -51,12 +51,12 @@ function _mergeEnvironmentValue(env: ITerminalEnvironment, key: string, value: s } } -export function addTerminalEnvironmentKeys(env: platform.IProcessEnvironment, version: string | undefined, locale: string | undefined, setLocaleVariables: boolean): void { +export function addTerminalEnvironmentKeys(env: platform.IProcessEnvironment, version: string | undefined, locale: string | undefined, detectLocale: 'auto' | 'off' | 'on'): void { env['TERM_PROGRAM'] = 'vscode'; if (version) { env['TERM_PROGRAM_VERSION'] = version; } - if (setLocaleVariables) { + if (_shouldSetLangEnvVariable(env, detectLocale)) { env['LANG'] = _getLangEnvVariable(locale); } env['COLORTERM'] = 'truecolor'; @@ -88,6 +88,16 @@ function resolveConfigurationVariables(configurationResolverService: IConfigurat return env; } +function _shouldSetLangEnvVariable(env: platform.IProcessEnvironment, detectLocale: 'auto' | 'off' | 'on'): boolean { + if (detectLocale === 'on') { + return true; + } + if (detectLocale === 'auto') { + return !env['LANG'] || env['LANG'].search(/\.UTF\-8$/) === -1; + } + return false; // 'off' +} + function _getLangEnvVariable(locale?: string): string { const parts = locale ? locale.split('-') : []; const n = parts.length; @@ -334,7 +344,7 @@ export function createTerminalEnvironment( configurationResolverService: IConfigurationResolverService | undefined, isWorkspaceShellAllowed: boolean, version: string | undefined, - setLocaleVariables: boolean, + detectLocale: 'auto' | 'off' | 'on', baseEnv: platform.IProcessEnvironment ): platform.IProcessEnvironment { // Create a terminal environment based on settings, launch config and permissions @@ -369,7 +379,7 @@ export function createTerminalEnvironment( mergeEnvironments(env, shellLaunchConfig.env); // Adding other env keys necessary to create the process - addTerminalEnvironmentKeys(env, version, platform.locale, setLocaleVariables); + addTerminalEnvironmentKeys(env, version, platform.locale, detectLocale); } return env; } From 6eaa4c5c30d4b2fbb085567bb6bfe8082f97a892 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 12 Sep 2019 16:18:43 -0700 Subject: [PATCH 4/6] Improve detectLocale description --- .../workbench/contrib/terminal/browser/terminal.contribution.ts | 2 +- .../contrib/terminal/browser/terminalProcessManager.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts index 9b8d567520cb3..738b3c092ace6 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminal.contribution.ts @@ -195,7 +195,7 @@ configurationRegistry.registerConfiguration({ default: 1000 }, 'terminal.integrated.detectLocale': { - markdownDescription: nls.localize('terminal.integrated.detectLocale', "Controls whether to detect and set the `$LANG` environment variable."), + markdownDescription: nls.localize('terminal.integrated.detectLocale', "Controls whether to detect and set the `$LANG` environment variable to a UTF-8 compliant option since VS Code's terminal only supports UTF-8 encoded data coming from the shell."), type: 'string', enum: ['auto', 'off', 'on'], enumDescriptions: [ diff --git a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts index d99d8de0ab15f..22a80f60ca54b 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalProcessManager.ts @@ -227,7 +227,7 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce const isWorkspaceShellAllowed = this._configHelper.checkWorkspaceShellPermissions(); this._configHelper.showRecommendations(shellLaunchConfig); const baseEnv = this._configHelper.config.inheritEnv ? processEnv : await this._terminalInstanceService.getMainProcessParentEnv(); - const env = terminalEnvironment.createTerminalEnvironment(shellLaunchConfig, lastActiveWorkspace, envFromConfigValue, this._configurationResolverService, isWorkspaceShellAllowed, this._productService.version, this._configHelper.config.setLocaleVariables, baseEnv); + const env = terminalEnvironment.createTerminalEnvironment(shellLaunchConfig, lastActiveWorkspace, envFromConfigValue, this._configurationResolverService, isWorkspaceShellAllowed, this._productService.version, this._configHelper.config.detectLocale, baseEnv); const useConpty = this._configHelper.config.windowsEnableConpty && !isScreenReaderModeEnabled; return this._terminalInstanceService.createTerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, useConpty); From e2e98f562818f933bc7ef4daa29861b3848018ad Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 12 Sep 2019 16:23:43 -0700 Subject: [PATCH 5/6] Fix test compile --- .../terminal/test/node/terminalEnvironment.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts b/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts index 1f8ecd4417140..d110a9ea6b2a3 100644 --- a/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts +++ b/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts @@ -13,21 +13,21 @@ suite('Workbench - TerminalEnvironment', () => { test('addTerminalEnvironmentKeys', () => { const env: { [key: string]: any } = { FOO: 'bar' }; const locale = 'en-au'; - terminalEnvironment.addTerminalEnvironmentKeys(env, '1.2.3', locale, true); + terminalEnvironment.addTerminalEnvironmentKeys(env, '1.2.3', locale, 'on'); assert.equal(env['TERM_PROGRAM'], 'vscode'); assert.equal(env['TERM_PROGRAM_VERSION'], '1.2.3'); assert.equal(env['LANG'], 'en_AU.UTF-8', 'LANG is equal to the requested locale with UTF-8'); const env2: { [key: string]: any } = { FOO: 'bar' }; - terminalEnvironment.addTerminalEnvironmentKeys(env2, '1.2.3', undefined, true); + terminalEnvironment.addTerminalEnvironmentKeys(env2, '1.2.3', undefined, 'on'); assert.equal(env2['LANG'], 'en_US.UTF-8', 'LANG is equal to en_US.UTF-8 as fallback.'); // More info on issue #14586 const env3 = { LANG: 'replace' }; - terminalEnvironment.addTerminalEnvironmentKeys(env3, '1.2.3', undefined, true); + terminalEnvironment.addTerminalEnvironmentKeys(env3, '1.2.3', undefined, 'on'); assert.equal(env3['LANG'], 'en_US.UTF-8', 'LANG is set to the fallback LANG'); const env4 = { LANG: 'en_US.UTF-8' }; - terminalEnvironment.addTerminalEnvironmentKeys(env3, '1.2.3', undefined, true); + terminalEnvironment.addTerminalEnvironmentKeys(env3, '1.2.3', undefined, 'on'); assert.equal(env4['LANG'], 'en_US.UTF-8', 'LANG is equal to the parent environment\'s LANG'); }); From d68d86d2dbc3d11d1c1bd9883d02e6d3a13bb478 Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Thu, 12 Sep 2019 18:00:54 -0700 Subject: [PATCH 6/6] Improve testing around terminal env vars --- .../api/node/extHostTerminalService.ts | 2 +- .../terminal/common/terminalEnvironment.ts | 8 +- .../test/node/terminalEnvironment.test.ts | 158 +++++++++++++----- 3 files changed, 124 insertions(+), 44 deletions(-) diff --git a/src/vs/workbench/api/node/extHostTerminalService.ts b/src/vs/workbench/api/node/extHostTerminalService.ts index cd1a75c5406e3..cf474ae37ad63 100644 --- a/src/vs/workbench/api/node/extHostTerminalService.ts +++ b/src/vs/workbench/api/node/extHostTerminalService.ts @@ -182,7 +182,7 @@ export class ExtHostTerminalService extends BaseExtHostTerminalService { this._variableResolver, isWorkspaceShellAllowed, pkg.version, - terminalConfig.get('detectLocale', 'auto'), + terminalConfig.get<'auto' | 'off' | 'on'>('detectLocale', 'auto'), baseEnv ); diff --git a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts index 69a3ea4c9f36f..171e639c20f02 100644 --- a/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts +++ b/src/vs/workbench/contrib/terminal/common/terminalEnvironment.ts @@ -56,8 +56,8 @@ export function addTerminalEnvironmentKeys(env: platform.IProcessEnvironment, ve if (version) { env['TERM_PROGRAM_VERSION'] = version; } - if (_shouldSetLangEnvVariable(env, detectLocale)) { - env['LANG'] = _getLangEnvVariable(locale); + if (shouldSetLangEnvVariable(env, detectLocale)) { + env['LANG'] = getLangEnvVariable(locale); } env['COLORTERM'] = 'truecolor'; } @@ -88,7 +88,7 @@ function resolveConfigurationVariables(configurationResolverService: IConfigurat return env; } -function _shouldSetLangEnvVariable(env: platform.IProcessEnvironment, detectLocale: 'auto' | 'off' | 'on'): boolean { +export function shouldSetLangEnvVariable(env: platform.IProcessEnvironment, detectLocale: 'auto' | 'off' | 'on'): boolean { if (detectLocale === 'on') { return true; } @@ -98,7 +98,7 @@ function _shouldSetLangEnvVariable(env: platform.IProcessEnvironment, detectLoca return false; // 'off' } -function _getLangEnvVariable(locale?: string): string { +export function getLangEnvVariable(locale?: string): string { const parts = locale ? locale.split('-') : []; const n = parts.length; if (n === 0) { diff --git a/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts b/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts index d110a9ea6b2a3..166161c805748 100644 --- a/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts +++ b/src/vs/workbench/contrib/terminal/test/node/terminalEnvironment.test.ts @@ -5,30 +5,110 @@ import * as assert from 'assert'; import * as platform from 'vs/base/common/platform'; -import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; import { URI as Uri } from 'vs/base/common/uri'; import { IStringDictionary } from 'vs/base/common/collections'; +import { addTerminalEnvironmentKeys, mergeEnvironments, getCwd, getDefaultShell, getLangEnvVariable, shouldSetLangEnvVariable } from 'vs/workbench/contrib/terminal/common/terminalEnvironment'; suite('Workbench - TerminalEnvironment', () => { - test('addTerminalEnvironmentKeys', () => { - const env: { [key: string]: any } = { FOO: 'bar' }; - const locale = 'en-au'; - terminalEnvironment.addTerminalEnvironmentKeys(env, '1.2.3', locale, 'on'); - assert.equal(env['TERM_PROGRAM'], 'vscode'); - assert.equal(env['TERM_PROGRAM_VERSION'], '1.2.3'); - assert.equal(env['LANG'], 'en_AU.UTF-8', 'LANG is equal to the requested locale with UTF-8'); - - const env2: { [key: string]: any } = { FOO: 'bar' }; - terminalEnvironment.addTerminalEnvironmentKeys(env2, '1.2.3', undefined, 'on'); - assert.equal(env2['LANG'], 'en_US.UTF-8', 'LANG is equal to en_US.UTF-8 as fallback.'); // More info on issue #14586 - - const env3 = { LANG: 'replace' }; - terminalEnvironment.addTerminalEnvironmentKeys(env3, '1.2.3', undefined, 'on'); - assert.equal(env3['LANG'], 'en_US.UTF-8', 'LANG is set to the fallback LANG'); - - const env4 = { LANG: 'en_US.UTF-8' }; - terminalEnvironment.addTerminalEnvironmentKeys(env3, '1.2.3', undefined, 'on'); - assert.equal(env4['LANG'], 'en_US.UTF-8', 'LANG is equal to the parent environment\'s LANG'); + suite('addTerminalEnvironmentKeys', () => { + test('should set expected variables', () => { + const env: { [key: string]: any } = {}; + addTerminalEnvironmentKeys(env, '1.2.3', 'en', 'on'); + assert.equal(env['TERM_PROGRAM'], 'vscode'); + assert.equal(env['TERM_PROGRAM_VERSION'], '1.2.3'); + assert.equal(env['COLORTERM'], 'truecolor'); + assert.equal(env['LANG'], 'en_US.UTF-8'); + }); + test('should use language variant for LANG that is provided in locale', () => { + const env: { [key: string]: any } = {}; + addTerminalEnvironmentKeys(env, '1.2.3', 'en-au', 'on'); + assert.equal(env['LANG'], 'en_AU.UTF-8', 'LANG is equal to the requested locale with UTF-8'); + }); + test('should fallback to en_US when no locale is provided', () => { + const env2: { [key: string]: any } = { FOO: 'bar' }; + addTerminalEnvironmentKeys(env2, '1.2.3', undefined, 'on'); + assert.equal(env2['LANG'], 'en_US.UTF-8', 'LANG is equal to en_US.UTF-8 as fallback.'); // More info on issue #14586 + }); + test('should fallback to en_US when an invalid locale is provided', () => { + const env3 = { LANG: 'replace' }; + addTerminalEnvironmentKeys(env3, '1.2.3', undefined, 'on'); + assert.equal(env3['LANG'], 'en_US.UTF-8', 'LANG is set to the fallback LANG'); + }); + test('should override existing LANG', () => { + const env4 = { LANG: 'en_AU.UTF-8' }; + addTerminalEnvironmentKeys(env4, '1.2.3', undefined, 'on'); + assert.equal(env4['LANG'], 'en_US.UTF-8', 'LANG is equal to the parent environment\'s LANG'); + }); + }); + + suite('shouldSetLangEnvVariable', () => { + test('auto', () => { + assert.equal(shouldSetLangEnvVariable({}, 'auto'), true); + assert.equal(shouldSetLangEnvVariable({ LANG: 'en-US' }, 'auto'), true); + assert.equal(shouldSetLangEnvVariable({ LANG: 'en-US.UTF-8' }, 'auto'), false); + }); + test('off', () => { + assert.equal(shouldSetLangEnvVariable({}, 'off'), false); + assert.equal(shouldSetLangEnvVariable({ LANG: 'en-US' }, 'off'), false); + assert.equal(shouldSetLangEnvVariable({ LANG: 'en-US.UTF-8' }, 'off'), false); + }); + test('on', () => { + assert.equal(shouldSetLangEnvVariable({}, 'on'), true); + assert.equal(shouldSetLangEnvVariable({ LANG: 'en-US' }, 'on'), true); + assert.equal(shouldSetLangEnvVariable({ LANG: 'en-US.UTF-8' }, 'on'), true); + }); + }); + + suite('getLangEnvVariable', () => { + test('should fallback to en_US when no locale is provided', () => { + assert.equal(getLangEnvVariable(undefined), 'en_US.UTF-8'); + assert.equal(getLangEnvVariable(''), 'en_US.UTF-8'); + }); + test('should fallback to default language variants when variant isn\'t provided', () => { + assert.equal(getLangEnvVariable('af'), 'af_ZA.UTF-8'); + assert.equal(getLangEnvVariable('am'), 'am_ET.UTF-8'); + assert.equal(getLangEnvVariable('be'), 'be_BY.UTF-8'); + assert.equal(getLangEnvVariable('bg'), 'bg_BG.UTF-8'); + assert.equal(getLangEnvVariable('ca'), 'ca_ES.UTF-8'); + assert.equal(getLangEnvVariable('cs'), 'cs_CZ.UTF-8'); + assert.equal(getLangEnvVariable('da'), 'da_DK.UTF-8'); + assert.equal(getLangEnvVariable('de'), 'de_DE.UTF-8'); + assert.equal(getLangEnvVariable('el'), 'el_GR.UTF-8'); + assert.equal(getLangEnvVariable('en'), 'en_US.UTF-8'); + assert.equal(getLangEnvVariable('es'), 'es_ES.UTF-8'); + assert.equal(getLangEnvVariable('et'), 'et_EE.UTF-8'); + assert.equal(getLangEnvVariable('eu'), 'eu_ES.UTF-8'); + assert.equal(getLangEnvVariable('fi'), 'fi_FI.UTF-8'); + assert.equal(getLangEnvVariable('fr'), 'fr_FR.UTF-8'); + assert.equal(getLangEnvVariable('he'), 'he_IL.UTF-8'); + assert.equal(getLangEnvVariable('hr'), 'hr_HR.UTF-8'); + assert.equal(getLangEnvVariable('hu'), 'hu_HU.UTF-8'); + assert.equal(getLangEnvVariable('hy'), 'hy_AM.UTF-8'); + assert.equal(getLangEnvVariable('is'), 'is_IS.UTF-8'); + assert.equal(getLangEnvVariable('it'), 'it_IT.UTF-8'); + assert.equal(getLangEnvVariable('ja'), 'ja_JP.UTF-8'); + assert.equal(getLangEnvVariable('kk'), 'kk_KZ.UTF-8'); + assert.equal(getLangEnvVariable('ko'), 'ko_KR.UTF-8'); + assert.equal(getLangEnvVariable('lt'), 'lt_LT.UTF-8'); + assert.equal(getLangEnvVariable('nl'), 'nl_NL.UTF-8'); + assert.equal(getLangEnvVariable('no'), 'no_NO.UTF-8'); + assert.equal(getLangEnvVariable('pl'), 'pl_PL.UTF-8'); + assert.equal(getLangEnvVariable('pt'), 'pt_BR.UTF-8'); + assert.equal(getLangEnvVariable('ro'), 'ro_RO.UTF-8'); + assert.equal(getLangEnvVariable('ru'), 'ru_RU.UTF-8'); + assert.equal(getLangEnvVariable('sk'), 'sk_SK.UTF-8'); + assert.equal(getLangEnvVariable('sl'), 'sl_SI.UTF-8'); + assert.equal(getLangEnvVariable('sr'), 'sr_YU.UTF-8'); + assert.equal(getLangEnvVariable('sv'), 'sv_SE.UTF-8'); + assert.equal(getLangEnvVariable('tr'), 'tr_TR.UTF-8'); + assert.equal(getLangEnvVariable('uk'), 'uk_UA.UTF-8'); + assert.equal(getLangEnvVariable('zh'), 'zh_CN.UTF-8'); + }); + test('should set language variant based on full locale', () => { + assert.equal(getLangEnvVariable('en-AU'), 'en_AU.UTF-8'); + assert.equal(getLangEnvVariable('en-au'), 'en_AU.UTF-8'); + assert.equal(getLangEnvVariable('fa-ke'), 'fa_KE.UTF-8'); + }); }); suite('mergeEnvironments', () => { @@ -39,7 +119,7 @@ suite('Workbench - TerminalEnvironment', () => { const other = { c: 'd' }; - terminalEnvironment.mergeEnvironments(parent, other); + mergeEnvironments(parent, other); assert.deepEqual(parent, { a: 'b', c: 'd' @@ -56,7 +136,7 @@ suite('Workbench - TerminalEnvironment', () => { const other = { A: 'c' }; - terminalEnvironment.mergeEnvironments(parent, other); + mergeEnvironments(parent, other); assert.deepEqual(parent, { a: 'c' }); @@ -70,7 +150,7 @@ suite('Workbench - TerminalEnvironment', () => { const other: IStringDictionary = { a: null }; - terminalEnvironment.mergeEnvironments(parent, other); + mergeEnvironments(parent, other); assert.deepEqual(parent, { c: 'd' }); @@ -87,7 +167,7 @@ suite('Workbench - TerminalEnvironment', () => { const other: IStringDictionary = { A: null }; - terminalEnvironment.mergeEnvironments(parent, other); + mergeEnvironments(parent, other); assert.deepEqual(parent, { c: 'd' }); @@ -101,37 +181,37 @@ suite('Workbench - TerminalEnvironment', () => { } test('should default to userHome for an empty workspace', () => { - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, undefined), '/userHome/'); + assertPathsMatch(getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, undefined), '/userHome/'); }); test('should use to the workspace if it exists', () => { - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, Uri.file('/foo'), undefined), '/foo'); + assertPathsMatch(getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, Uri.file('/foo'), undefined), '/foo'); }); test('should use an absolute custom cwd as is', () => { - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, '/foo'), '/foo'); + assertPathsMatch(getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, '/foo'), '/foo'); }); test('should normalize a relative custom cwd against the workspace path', () => { - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, Uri.file('/bar'), 'foo'), '/bar/foo'); - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, Uri.file('/bar'), './foo'), '/bar/foo'); - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, Uri.file('/bar'), '../foo'), '/foo'); + assertPathsMatch(getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, Uri.file('/bar'), 'foo'), '/bar/foo'); + assertPathsMatch(getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, Uri.file('/bar'), './foo'), '/bar/foo'); + assertPathsMatch(getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, Uri.file('/bar'), '../foo'), '/foo'); }); test('should fall back for relative a custom cwd that doesn\'t have a workspace', () => { - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, 'foo'), '/userHome/'); - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, './foo'), '/userHome/'); - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, '../foo'), '/userHome/'); + assertPathsMatch(getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, 'foo'), '/userHome/'); + assertPathsMatch(getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, './foo'), '/userHome/'); + assertPathsMatch(getCwd({ executable: undefined, args: [] }, '/userHome/', undefined, undefined, undefined, '../foo'), '/userHome/'); }); test('should ignore custom cwd when told to ignore', () => { - assertPathsMatch(terminalEnvironment.getCwd({ executable: undefined, args: [], ignoreConfigurationCwd: true }, '/userHome/', undefined, undefined, Uri.file('/bar'), '/foo'), '/bar'); + assertPathsMatch(getCwd({ executable: undefined, args: [], ignoreConfigurationCwd: true }, '/userHome/', undefined, undefined, Uri.file('/bar'), '/foo'), '/bar'); }); }); suite('getDefaultShell', () => { test('should change Sysnative to System32 in non-WoW64 systems', () => { - const shell = terminalEnvironment.getDefaultShell(key => { + const shell = getDefaultShell(key => { return ({ 'terminal.integrated.shell.windows': { user: 'C:\\Windows\\Sysnative\\cmd.exe', value: undefined, default: undefined } } as any)[key]; @@ -140,7 +220,7 @@ suite('Workbench - TerminalEnvironment', () => { }); test('should not change Sysnative to System32 in WoW64 systems', () => { - const shell = terminalEnvironment.getDefaultShell(key => { + const shell = getDefaultShell(key => { return ({ 'terminal.integrated.shell.windows': { user: 'C:\\Windows\\Sysnative\\cmd.exe', value: undefined, default: undefined } } as any)[key]; @@ -149,21 +229,21 @@ suite('Workbench - TerminalEnvironment', () => { }); test('should use automationShell when specified', () => { - const shell1 = terminalEnvironment.getDefaultShell(key => { + const shell1 = getDefaultShell(key => { return ({ 'terminal.integrated.shell.windows': { user: 'shell', value: undefined, default: undefined }, 'terminal.integrated.automationShell.windows': { user: undefined, value: undefined, default: undefined } } as any)[key]; }, false, 'DEFAULT', false, 'C:\\Windows', undefined, undefined, {} as any, false, platform.Platform.Windows); assert.equal(shell1, 'shell', 'automationShell was false'); - const shell2 = terminalEnvironment.getDefaultShell(key => { + const shell2 = getDefaultShell(key => { return ({ 'terminal.integrated.shell.windows': { user: 'shell', value: undefined, default: undefined }, 'terminal.integrated.automationShell.windows': { user: undefined, value: undefined, default: undefined } } as any)[key]; }, false, 'DEFAULT', false, 'C:\\Windows', undefined, undefined, {} as any, true, platform.Platform.Windows); assert.equal(shell2, 'shell', 'automationShell was true'); - const shell3 = terminalEnvironment.getDefaultShell(key => { + const shell3 = getDefaultShell(key => { return ({ 'terminal.integrated.shell.windows': { user: 'shell', value: undefined, default: undefined }, 'terminal.integrated.automationShell.windows': { user: 'automationShell', value: undefined, default: undefined }