提交 775c6431 编写于 作者: D Daniel Imms

Factor out terminal config logic and add tests

上级 59f29cae
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import {getBaseThemeId} from 'vs/platform/theme/common/themes';
import {Platform} from 'vs/base/common/platform';
import {IConfiguration} from 'vs/editor/common/config/defaultConfig';
import {IConfigurationService} from 'vs/platform/configuration/common/configuration';
import {ITerminalConfiguration} from 'vs/workbench/parts/terminal/electron-browser/terminal';
import {IThemeService} from 'vs/workbench/services/themes/common/themeService';
const DEFAULT_ANSI_COLORS = {
'hc-black': [
'#000000', // black
'#cd0000', // red
'#00cd00', // green
'#cdcd00', // yellow
'#0000ee', // blue
'#cd00cd', // magenta
'#00cdcd', // cyan
'#e5e5e5', // white
'#7f7f7f', // bright black
'#ff0000', // bright red
'#00ff00', // bright green
'#ffff00', // bright yellow
'#5c5cff', // bright blue
'#ff00ff', // bright magenta
'#00ffff', // bright cyan
'#ffffff' // bright white
],
'vs': [
'#000000', // black
'#cd3131', // red
'#008000', // green
'#949800', // yellow
'#0451a5', // blue
'#bc05bc', // magenta
'#0598bc', // cyan
'#555555', // white
'#666666', // bright black
'#cd3131', // bright red
'#00aa00', // bright green
'#b5ba00', // bright yellow
'#0451a5', // bright blue
'#bc05bc', // bright magenta
'#0598bc', // bright cyan
'#a5a5a5' // bright white
],
'vs-dark': [
'#000000', // black
'#cd3131', // red
'#09885a', // green
'#e5e510', // yellow
'#2472c8', // blue
'#bc3fbc', // magenta
'#11a8cd', // cyan
'#e5e5e5', // white
'#666666', // bright black
'#f14c4c', // bright red
'#17a773', // bright green
'#f5f543', // bright yellow
'#3b8eea', // bright blue
'#d670d6', // bright magenta
'#29b8db', // bright cyan
'#e5e5e5' // bright white
]
};
/**
* Encapsulates terminal configuration logic, the primary purpose of this file is so that platform
* specific test cases can be written.
*/
export class TerminalConfigHelper {
public constructor(
private platform: Platform,
private configurationService: IConfigurationService,
private themeService: IThemeService) {
}
public getTheme(): string[] {
let baseThemeId = getBaseThemeId(this.themeService.getTheme());
return DEFAULT_ANSI_COLORS[baseThemeId];
}
/**
* Set the terminal font to `terminal.integrated.fontFamily` if it is set, otherwise fallback to
* `editor.fontFamily`.
*/
public getFontFamily() {
let terminalConfig = this.configurationService.getConfiguration<ITerminalConfiguration>();
let fontFamily = terminalConfig.terminal.integrated.fontFamily;
if (!fontFamily) {
let editorConfig = this.configurationService.getConfiguration<IConfiguration>();
fontFamily = editorConfig.editor.fontFamily;
}
return fontFamily;
}
public getShell(): string {
let config = this.configurationService.getConfiguration<ITerminalConfiguration>();
if (this.platform === Platform.Windows) {
return config.terminal.integrated.shell.windows;
}
if (this.platform === Platform.Mac) {
return config.terminal.integrated.shell.osx;
}
return config.terminal.integrated.shell.linux;
}
}
\ No newline at end of file
......@@ -11,80 +11,22 @@ import path = require('path');
import URI from 'vs/base/common/uri';
import DOM = require('vs/base/browser/dom');
import platform = require('vs/base/common/platform');
import {getBaseThemeId} from 'vs/platform/theme/common/themes';
import {TPromise} from 'vs/base/common/winjs.base';
import {Builder, Dimension} from 'vs/base/browser/builder';
import {IConfiguration} from 'vs/editor/common/config/defaultConfig';
import {IConfigurationService} from 'vs/platform/configuration/common/configuration';
import {IStringDictionary} from 'vs/base/common/collections';
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {IThemeService} from 'vs/workbench/services/themes/common/themeService';
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
import {ITerminalConfiguration, ITerminalService, TERMINAL_PANEL_ID} from 'vs/workbench/parts/terminal/electron-browser/terminal';
import {ITerminalService, TERMINAL_PANEL_ID} from 'vs/workbench/parts/terminal/electron-browser/terminal';
import {Panel} from 'vs/workbench/browser/panel';
import {DomScrollableElement} from 'vs/base/browser/ui/scrollbar/scrollableElement';
import {ScrollbarVisibility} from 'vs/base/browser/ui/scrollbar/scrollableElementOptions';
import {TerminalConfigHelper} from 'vs/workbench/parts/terminal/electron-browser/terminalConfigHelper';
const TERMINAL_CHAR_WIDTH = 8;
const TERMINAL_CHAR_HEIGHT = 18;
const DEFAULT_ANSI_COLORS = {
'hc-black': [
'#000000', // black
'#cd0000', // red
'#00cd00', // green
'#cdcd00', // yellow
'#0000ee', // blue
'#cd00cd', // magenta
'#00cdcd', // cyan
'#e5e5e5', // white
'#7f7f7f', // bright black
'#ff0000', // bright red
'#00ff00', // bright green
'#ffff00', // bright yellow
'#5c5cff', // bright blue
'#ff00ff', // bright magenta
'#00ffff', // bright cyan
'#ffffff' // bright white
],
'vs': [
'#000000', // black
'#cd3131', // red
'#008000', // green
'#949800', // yellow
'#0451a5', // blue
'#bc05bc', // magenta
'#0598bc', // cyan
'#555555', // white
'#666666', // bright black
'#cd3131', // bright red
'#00aa00', // bright green
'#b5ba00', // bright yellow
'#0451a5', // bright blue
'#bc05bc', // bright magenta
'#0598bc', // bright cyan
'#a5a5a5' // bright white
],
'vs-dark': [
'#000000', // black
'#cd3131', // red
'#09885a', // green
'#e5e510', // yellow
'#2472c8', // blue
'#bc3fbc', // magenta
'#11a8cd', // cyan
'#e5e5e5', // white
'#666666', // bright black
'#f14c4c', // bright red
'#17a773', // bright green
'#f5f543', // bright yellow
'#3b8eea', // bright blue
'#d670d6', // bright magenta
'#29b8db', // bright cyan
'#e5e5e5' // bright white
]
};
export class TerminalPanel extends Panel {
private toDispose: lifecycle.IDisposable[];
......@@ -92,6 +34,7 @@ export class TerminalPanel extends Panel {
private parentDomElement: HTMLElement;
private terminal;
private terminalDomElement: HTMLDivElement;
private configurationHelper: TerminalConfigHelper;
constructor(
@IConfigurationService private configurationService: IConfigurationService,
......@@ -101,6 +44,7 @@ export class TerminalPanel extends Panel {
@IThemeService private themeService: IThemeService
) {
super(TERMINAL_PANEL_ID, telemetryService);
this.configurationHelper = new TerminalConfigHelper(platform.platform, this.configurationService, this.themeService);
this.toDispose = [];
}
......@@ -144,7 +88,7 @@ export class TerminalPanel extends Panel {
private createTerminalProcess(): cp.ChildProcess {
let env = this.cloneEnv();
env['PTYSHELL'] = this.getShell();
env['PTYSHELL'] = this.configurationHelper.getShell();
env['PTYCWD'] = this.contextService.getWorkspace() ? this.contextService.getWorkspace().resource.fsPath : os.homedir();
return cp.fork('./terminalProcess', [], {
env: env,
......@@ -229,8 +173,7 @@ export class TerminalPanel extends Panel {
if (!this.terminal) {
return;
}
let baseThemeId = getBaseThemeId(this.themeService.getTheme());
this.terminal.colors = DEFAULT_ANSI_COLORS[baseThemeId];
this.terminal.colors = this.configurationHelper.getTheme();
this.terminal.refresh(0, this.terminal.rows);
}
......@@ -239,13 +182,7 @@ export class TerminalPanel extends Panel {
* `editor.fontFamily`.
*/
private setTerminalFont() {
let terminalConfig = this.configurationService.getConfiguration<ITerminalConfiguration>();
let fontFamily = terminalConfig.terminal.integrated.fontFamily;
if (!fontFamily) {
let editorConfig = this.configurationService.getConfiguration<IConfiguration>();
fontFamily = editorConfig.editor.fontFamily;
}
this.terminalDomElement.style.fontFamily = fontFamily;
this.terminalDomElement.style.fontFamily = this.configurationHelper.getFontFamily();
}
public focus(): void {
......@@ -265,17 +202,6 @@ export class TerminalPanel extends Panel {
}
}
private getShell(): string {
let config = this.configurationService.getConfiguration<ITerminalConfiguration>();
if (platform.isWindows) {
return config.terminal.integrated.shell.windows;
}
if (platform.isMacintosh) {
return config.terminal.integrated.shell.osx;
}
return config.terminal.integrated.shell.linux;
}
public dispose(): void {
this.toDispose = lifecycle.dispose(this.toDispose);
this.terminal.destroy();
......
/*---------------------------------------------------------------------------------------------
* 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 Event from 'vs/base/common/event';
import {IConfigurationService} from 'vs/platform/configuration/common/configuration';
import {IThemeData} from 'vs/workbench/services/themes/common/themeService';
import {IThemeService} from 'vs/workbench/services/themes/common/themeService';
import {Platform} from 'vs/base/common/platform';
import {ServiceIdentifier} from 'vs/platform/instantiation/common/instantiation';
import {TPromise} from 'vs/base/common/winjs.base';
import {TerminalConfigHelper} from 'vs/workbench/parts/terminal/electron-browser/terminalConfigHelper';
class MockConfigurationService implements IConfigurationService {
public serviceId = IConfigurationService;
public constructor(private configuration: any = {}) {}
public loadConfiguration<T>(section?: string): TPromise<T> { return TPromise.as(this.getConfiguration()); }
public getConfiguration(): any { return this.configuration; }
public hasWorkspaceConfiguration(): boolean { return false; }
public onDidUpdateConfiguration() { return { dispose() { } }; }
public setUserConfiguration(key: any, value: any): Thenable<void> { return TPromise.as(null); }
}
class MockThemeService implements IThemeService {
public constructor(private activeTheme: string = undefined) {}
public serviceId: ServiceIdentifier<any>;
public setTheme(themeId: string, broadcastToAllWindows: boolean): TPromise<boolean> { return null; }
public getTheme(): string { return this.activeTheme; }
public getThemes(): TPromise<IThemeData[]> { return null; }
public onDidThemeChange: Event<string>;
}
suite('Workbench - TerminalConfigHelper', () => {
test('TerminalConfigHelper - getFontFamily', function () {
let themeService: IThemeService = new MockThemeService();
let configurationService: IConfigurationService;
let configHelper: TerminalConfigHelper;
configurationService = new MockConfigurationService({
editor: {
fontFamily: 'foo'
},
terminal: {
integrated: {
fontFamily: 'bar'
}
}
});
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService, themeService);
assert.equal(configHelper.getFontFamily(), 'bar', 'terminal.integrated.fontFamily should be selected over editor.fontFamily');
configurationService = new MockConfigurationService({
editor: {
fontFamily: 'foo'
},
terminal: {
integrated: {
fontFamily: undefined
}
}
});
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService, themeService);
assert.equal(configHelper.getFontFamily(), 'foo', 'editor.fontFamily should be the fallback when terminal.integrated.fontFamily not set');
});
test('TerminalConfigHelper - getShell', function () {
let themeService: IThemeService = new MockThemeService();
let configurationService: IConfigurationService;
let configHelper: TerminalConfigHelper;
configurationService = new MockConfigurationService({
terminal: {
integrated: {
shell: {
linux: 'foo'
}
}
}
});
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService, themeService);
assert.equal(configHelper.getShell(), 'foo', 'terminal.integrated.shell.linux should be selected on Linux');
configurationService = new MockConfigurationService({
terminal: {
integrated: {
shell: {
osx: 'foo'
}
}
}
});
configHelper = new TerminalConfigHelper(Platform.Mac, configurationService, themeService);
assert.equal(configHelper.getShell(), 'foo', 'terminal.integrated.shell.osx should be selected on OS X');
configurationService = new MockConfigurationService({
terminal: {
integrated: {
shell: {
windows: 'foo'
}
}
}
});
configHelper = new TerminalConfigHelper(Platform.Windows, configurationService, themeService);
assert.equal(configHelper.getShell(), 'foo', 'terminal.integrated.shell.windows should be selected on Windows');
});
test('TerminalConfigHelper - getTheme', function () {
let configurationService: IConfigurationService = new MockConfigurationService();
let themeService: IThemeService;
let configHelper: TerminalConfigHelper;
themeService = new MockThemeService('hc-black foo');
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService, themeService);
assert.deepEqual(configHelper.getTheme(), [
'#000000',
'#cd0000',
'#00cd00',
'#cdcd00',
'#0000ee',
'#cd00cd',
'#00cdcd',
'#e5e5e5',
'#7f7f7f',
'#ff0000',
'#00ff00',
'#ffff00',
'#5c5cff',
'#ff00ff',
'#00ffff',
'#ffffff'
], 'The high contrast terminal theme should be selected when the hc-black theme is active');
themeService = new MockThemeService('vs foo');
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService, themeService);
assert.deepEqual(configHelper.getTheme(), [
'#000000',
'#cd3131',
'#008000',
'#949800',
'#0451a5',
'#bc05bc',
'#0598bc',
'#555555',
'#666666',
'#cd3131',
'#00aa00',
'#b5ba00',
'#0451a5',
'#bc05bc',
'#0598bc',
'#a5a5a5'
], 'The light terminal theme should be selected when a vs theme is active');
themeService = new MockThemeService('vs-dark foo');
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService, themeService);
assert.deepEqual(configHelper.getTheme(), [
'#000000',
'#cd3131',
'#09885a',
'#e5e510',
'#2472c8',
'#bc3fbc',
'#11a8cd',
'#e5e5e5',
'#666666',
'#f14c4c',
'#17a773',
'#f5f543',
'#3b8eea',
'#d670d6',
'#29b8db',
'#e5e5e5'
], 'The dark terminal theme should be selected when a vs-dark theme is active');
});
});
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册