提交 2af107b1 编写于 作者: C chrmarti 提交者: GitHub

Fixes #7301: Set LANG for terminal process (#8981)

Set LANG for terminal process and introduce setting to enable it.
上级 1ef9a66d
......@@ -6,6 +6,7 @@
import 'vs/css!./media/terminal';
import 'vs/css!./media/xterm';
import * as panel from 'vs/workbench/browser/panel';
import * as platform from 'vs/base/common/platform';
import nls = require('vs/nls');
import {Extensions, IConfigurationRegistry} from 'vs/platform/configuration/common/configurationRegistry';
import {KbExpr} from 'vs/platform/keybinding/common/keybinding';
......@@ -79,6 +80,11 @@ configurationRegistry.registerConfiguration({
'description': nls.localize('terminal.integrated.cursorBlinking', "Controls whether the terminal cursor blinks."),
'type': 'boolean',
'default': true
},
'terminal.integrated.setLocaleVariables': {
'description': nls.localize('terminal.integrated.setLocaleVariables', "Controls whether locale variables are set at startup of the terminal, this defaults to true on OS X, false on other platforms."),
'type': 'boolean',
'default': platform.isMacintosh
}
}
});
......
......@@ -43,7 +43,8 @@ export interface ITerminalConfiguration {
fontFamily: string,
fontLigatures: boolean,
fontSize: number,
lineHeight: number
lineHeight: number,
setLocaleVariables: boolean
}
};
}
......
......@@ -167,6 +167,11 @@ export class TerminalConfigHelper {
return shell;
}
public isSetLocaleVariables() {
let config = this.configurationService.getConfiguration<ITerminalConfiguration>();
return config.terminal.integrated.setLocaleVariables;
}
private toInteger(source: any, minimum?: number): number {
let r = parseInt(source, 10);
if (isNaN(r)) {
......
......@@ -20,9 +20,9 @@ import {IPanelService} from 'vs/workbench/services/panel/common/panelService';
import {IPartService} from 'vs/workbench/services/part/common/partService';
import {IStringDictionary} from 'vs/base/common/collections';
import {ITerminalProcess, ITerminalService, KEYBINDING_CONTEXT_TERMINAL_FOCUS, TERMINAL_PANEL_ID} from 'vs/workbench/parts/terminal/electron-browser/terminal';
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
import {IWorkspaceContextService, IWorkspace} from 'vs/platform/workspace/common/workspace';
import {TPromise} from 'vs/base/common/winjs.base';
import {TerminalConfigHelper} from 'vs/workbench/parts/terminal/electron-browser/terminalConfigHelper';
import {TerminalConfigHelper, IShell} from 'vs/workbench/parts/terminal/electron-browser/terminalConfigHelper';
import {TerminalPanel} from 'vs/workbench/parts/terminal/electron-browser/terminalPanel';
export class TerminalService implements ITerminalService {
......@@ -244,14 +244,8 @@ export class TerminalService implements ITerminalService {
}
private createTerminalProcess(): ITerminalProcess {
let env = this.cloneEnv();
let shell = this.configHelper.getShell();
env['PTYPID'] = process.pid.toString();
env['PTYSHELL'] = shell.executable;
shell.args.forEach((arg, i) => {
env[`PTYSHELLARG${i}`] = arg;
});
env['PTYCWD'] = this.contextService.getWorkspace() ? this.contextService.getWorkspace().resource.fsPath : os.homedir();
let locale = this.configHelper.isSetLocaleVariables() ? platform.locale : undefined;
let env = TerminalService.createTerminalEnv(process.env, this.configHelper.getShell(), this.contextService.getWorkspace(), locale);
let terminalProcess = {
title: '',
process: cp.fork('./terminalProcess', [], {
......@@ -272,11 +266,34 @@ export class TerminalService implements ITerminalService {
return terminalProcess;
}
private cloneEnv(): IStringDictionary<string> {
public static createTerminalEnv(parentEnv: IStringDictionary<string>, shell: IShell, workspace: IWorkspace, locale?: string): IStringDictionary<string> {
let env = this.cloneEnv(parentEnv);
env['PTYPID'] = process.pid.toString();
env['PTYSHELL'] = shell.executable;
shell.args.forEach((arg, i) => {
env[`PTYSHELLARG${i}`] = arg;
});
env['PTYCWD'] = workspace ? workspace.resource.fsPath : os.homedir();
if (locale) {
env['LANG'] = this.getLangEnvVariable(locale);
}
return env;
}
private static cloneEnv(env: IStringDictionary<string>): IStringDictionary<string> {
let newEnv: IStringDictionary<string> = Object.create(null);
Object.keys(process.env).forEach((key) => {
newEnv[key] = process.env[key];
Object.keys(env).forEach((key) => {
newEnv[key] = env[key];
});
return newEnv;
}
private static getLangEnvVariable(locale: string) {
const parts = locale.split('-');
const n = parts.length;
if (n > 1) {
parts[n - 1] = parts[n - 1].toUpperCase();
}
return parts.join('_') + '.UTF-8';
}
}
\ No newline at end of file
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import * as os from 'os';
import {IStringDictionary} from 'vs/base/common/collections';
import {IWorkspace} from 'vs/platform/workspace/common/workspace';
import {TerminalService} from 'vs/workbench/parts/terminal/electron-browser/terminalService';
suite('Workbench - TerminalService', () => {
test('TerminalService - createTerminalEnv', function () {
const shell1 = {
executable: '/bin/foosh',
args: ['-bar', 'baz']
};
const parentEnv1: IStringDictionary<string> = <any>{
ok: true
};
const env1 = TerminalService.createTerminalEnv(parentEnv1, shell1, null, 'en-au');
assert.ok(env1['ok'], 'Parent environment is copied');
assert.deepStrictEqual(parentEnv1, { ok: true }, 'Parent environment is unchanged');
assert.equal(env1['PTYPID'], process.pid.toString(), 'PTYPID is equal to the current PID');
assert.equal(env1['PTYSHELL'], '/bin/foosh', 'PTYSHELL is equal to the requested shell');
assert.equal(env1['PTYSHELLARG0'], '-bar', 'PTYSHELLARG0 is equal to the first shell argument');
assert.equal(env1['PTYSHELLARG1'], 'baz', 'PTYSHELLARG1 is equal to the first shell argument');
assert.ok(!('PTYSHELLARG2' in env1), 'PTYSHELLARG2 is unset');
assert.equal(env1['PTYCWD'], os.homedir(), 'PTYCWD is equal to the home folder');
assert.equal(env1['LANG'], 'en_AU.UTF-8', 'LANG is equal to the requested locale with UTF-8');
const shell2 = {
executable: '/bin/foosh',
args: []
};
const parentEnv2: IStringDictionary<string> = <any>{
LANG: 'en_US.UTF-8'
};
const workspace2: IWorkspace = <any>{
resource: {
fsPath: '/my/dev/folder'
}
};
const env2 = TerminalService.createTerminalEnv(parentEnv2, shell2, workspace2, 'en-au');
assert.ok(!('PTYSHELLARG0' in env2), 'PTYSHELLARG0 is unset');
assert.equal(env2['PTYCWD'], '/my/dev/folder', 'PTYCWD is equal to the workspace folder');
assert.equal(env2['LANG'], 'en_AU.UTF-8', 'LANG is equal to the requested locale with UTF-8');
const env3 = TerminalService.createTerminalEnv(parentEnv1, shell1, null, null);
assert.ok(!('LANG' in env3), 'LANG is unset');
const env4 = TerminalService.createTerminalEnv(parentEnv2, shell1, null, null);
assert.equal(env4['LANG'], 'en_US.UTF-8', 'LANG is equal to the parent environment\'s LANG');
});
});
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册