提交 d23dd1ee 编写于 作者: M Martin Aeschlimann

[themes] migrate terminal colors to new APIs

上级 3d2d1cfb
......@@ -62,7 +62,6 @@ export interface ITerminalConfiguration {
export interface ITerminalConfigHelper {
config: ITerminalConfiguration;
getTheme(baseThemeId: string): string[];
getFont(): ITerminalFont;
}
......
......@@ -28,6 +28,7 @@ import debugActions = require('vs/workbench/parts/debug/browser/debugActions');
import { KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { OpenNextRecentlyUsedEditorInGroupAction, OpenPreviousRecentlyUsedEditorInGroupAction, FocusActiveGroupAction } from 'vs/workbench/browser/parts/editor/editorActions';
import { DefaultConfig } from 'vs/editor/common/config/defaultConfig';
import { registerColors } from './terminalColorRegistry';
let configurationRegistry = <IConfigurationRegistry>Registry.as(Extensions.Configuration);
configurationRegistry.registerConfiguration({
......@@ -257,3 +258,5 @@ actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ClearTerminalAct
primary: KeyMod.CtrlCmd | KeyCode.KEY_K,
linux: { primary: null }
}, KEYBINDING_CONTEXT_TERMINAL_FOCUS, KeybindingsRegistry.WEIGHT.workbenchContrib(1)), 'Terminal: Clear', category);
registerColors();
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import nls = require('vs/nls');
import { registerColor, ColorIdentifier } from 'vs/platform/theme/common/colorRegistry';
/**
* The color identifiers for the terminal's ansi colors. The index in the array corresponds to the index
* of the color in the terminal color table.
*/
export const ansiColorIdentifiers: ColorIdentifier[] = [];
const ansiColorMap = {
terminalAnsiBlack: {
index: 0,
defaults: {
light: '#000000',
dark: '#000000',
hc: '#000000'
}
},
terminalAnsiRed: {
index: 1,
defaults: {
light: '#cd3131',
dark: '#cd3131',
hc: '#cd0000'
}
},
terminalAnsiGreen: {
index: 2,
defaults: {
light: '#00BC00',
dark: '#0DBC79',
hc: '#00cd00'
}
},
terminalAnsiYellow: {
index: 3,
defaults: {
light: '#949800',
dark: '#e5e510',
hc: '#cdcd00'
}
},
terminalAnsiBlue: {
index: 4,
defaults: {
light: '#0451a5',
dark: '#2472c8',
hc: '#0000ee'
}
},
terminalAnsiMagenta: {
index: 5,
defaults: {
light: '#bc05bc',
dark: '#bc3fbc',
hc: '#cd00cd'
}
},
terminalAnsiCyan: {
index: 6,
defaults: {
light: '#0598bc',
dark: '#11a8cd',
hc: '#00cdcd'
}
},
terminalAnsiWhite: {
index: 7,
defaults: {
light: '#555555',
dark: '#e5e5e5',
hc: '#e5e5e5'
}
},
terminalAnsiBrightBlack: {
index: 8,
defaults: {
light: '#666666',
dark: '#666666',
hc: '#7f7f7f'
}
},
terminalAnsiBrightRed: {
index: 9,
defaults: {
light: '#cd3131',
dark: '#f14c4c',
hc: '#ff0000'
}
},
terminalAnsiBrightGreen: {
index: 10,
defaults: {
light: '#14CE14',
dark: '#23d18b',
hc: '#00ff00'
}
},
terminalAnsiBrightYellow: {
index: 11,
defaults: {
light: '#b5ba00',
dark: '#f5f543',
hc: '#ffff00'
}
},
terminalAnsiBrightBlue: {
index: 12,
defaults: {
light: '#0451a5',
dark: '#3b8eea',
hc: '#5c5cff'
}
},
terminalAnsiBrightMagenta: {
index: 13,
defaults: {
light: '#bc05bc',
dark: '#d670d6',
hc: '#ff00ff'
}
},
terminalAnsiBrightCyan: {
index: 14,
defaults: {
light: '#0598bc',
dark: '#29b8db',
hc: '#00ffff'
}
},
terminalAnsiBrightWhite: {
index: 15,
defaults: {
light: '#a5a5a5',
dark: '#e5e5e5',
hc: '#ffffff'
}
}
};
export function registerColors(): void {
for (let id in ansiColorMap) {
let entry = ansiColorMap[id];
let colorName = id.substring(12);
ansiColorIdentifiers[entry.index] = registerColor(id, entry.defaults, nls.localize('terminal.ansiColor', '\'{0}\' ansi color in the terminal', colorName));
}
}
......@@ -16,63 +16,6 @@ interface IFullTerminalConfiguration {
const DEFAULT_LINE_HEIGHT = 1.2;
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
'#00BC00', // green
'#949800', // yellow
'#0451a5', // blue
'#bc05bc', // magenta
'#0598bc', // cyan
'#555555', // white
'#666666', // bright black
'#cd3131', // bright red
'#14CE14', // bright green
'#b5ba00', // bright yellow
'#0451a5', // bright blue
'#bc05bc', // bright magenta
'#0598bc', // bright cyan
'#a5a5a5' // bright white
],
'vs-dark': [
'#000000', // black
'#cd3131', // red
'#0DBC79', // green
'#e5e510', // yellow
'#2472c8', // blue
'#bc3fbc', // magenta
'#11a8cd', // cyan
'#e5e5e5', // white
'#666666', // bright black
'#f14c4c', // bright red
'#23d18b', // 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.
......@@ -92,10 +35,6 @@ export class TerminalConfigHelper implements ITerminalConfigHelper {
return this._configurationService.getConfiguration<IFullTerminalConfiguration>().terminal.integrated;
}
public getTheme(baseThemeId: string): string[] {
return DEFAULT_ANSI_COLORS[baseThemeId];
}
private _measureFont(fontFamily: string, fontSize: number, lineHeight: number): ITerminalFont {
// Create charMeasureElement if it hasn't been created or if it was orphaned by its parent
if (!this._charMeasureElement || !this._charMeasureElement.parentElement) {
......
......@@ -15,7 +15,9 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { ITerminalService, ITerminalFont, TERMINAL_PANEL_ID } from 'vs/workbench/parts/terminal/common/terminal';
import { IWorkbenchThemeService, IColorTheme } from 'vs/workbench/services/themes/common/themeService';
import { IThemeService, ITheme } from 'vs/platform/theme/common/themeService';
import { ansiColorIdentifiers } from './terminalColorRegistry';
import { ColorIdentifier } from 'vs/platform/theme/common/colorRegistry';
import { KillTerminalAction, CreateNewTerminalAction, SwitchTerminalInstanceAction, SwitchTerminalInstanceActionItem, CopyTerminalSelectionAction, TerminalPasteAction, ClearTerminalAction } from 'vs/workbench/parts/terminal/electron-browser/terminalActions';
import { Panel } from 'vs/workbench/browser/panel';
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
......@@ -26,7 +28,6 @@ export class TerminalPanel extends Panel {
private _actions: IAction[];
private _contextMenuActions: IAction[];
private _cancelContextMenu: boolean = false;
private _currentBaseThemeId: string;
private _font: ITerminalFont;
private _fontStyleElement: HTMLElement;
private _parentDomElement: HTMLElement;
......@@ -39,7 +40,7 @@ export class TerminalPanel extends Panel {
@IInstantiationService private _instantiationService: IInstantiationService,
@IKeybindingService private _keybindingService: IKeybindingService,
@ITerminalService private _terminalService: ITerminalService,
@IWorkbenchThemeService protected themeService: IWorkbenchThemeService,
@IThemeService protected themeService: IThemeService,
@ITelemetryService telemetryService: ITelemetryService
) {
super(TERMINAL_PANEL_ID, telemetryService, themeService);
......@@ -62,7 +63,7 @@ export class TerminalPanel extends Panel {
this._terminalService.setContainers(this.getContainer().getHTMLElement(), this._terminalContainer);
this._register(this.themeService.onDidColorThemeChange(theme => this._updateTheme(theme)));
this._register(this.themeService.onThemeChange(theme => this._updateTheme(theme)));
this._register(this._configurationService.onDidUpdateConfiguration(() => this._updateFont()));
this._updateFont();
this._updateTheme();
......@@ -196,40 +197,26 @@ export class TerminalPanel extends Panel {
}));
}
private _updateTheme(colorTheme?: IColorTheme): void {
if (!colorTheme) {
colorTheme = this.themeService.getColorTheme();
private _updateTheme(theme?: ITheme): void {
if (!theme) {
theme = this.themeService.getTheme();
}
let baseThemeId = colorTheme.getBaseThemeId();
if (baseThemeId === this._currentBaseThemeId) {
return;
}
this._currentBaseThemeId = baseThemeId;
let theme = this._terminalService.configHelper.getTheme(baseThemeId);
let css = '';
theme.forEach((color: string, index: number) => {
let rgba = this._convertHexCssColorToRgba(color, 0.996);
css += `.monaco-workbench .panel.integrated-terminal .xterm .xterm-color-${index} { color: ${color}; }` +
`.monaco-workbench .panel.integrated-terminal .xterm .xterm-color-${index}::selection { background-color: ${rgba}; }` +
`.monaco-workbench .panel.integrated-terminal .xterm .xterm-bg-color-${index} { background-color: ${color}; }` +
`.monaco-workbench .panel.integrated-terminal .xterm .xterm-bg-color-${index}::selection { color: ${color}; }`;
ansiColorIdentifiers.forEach((colorId: ColorIdentifier, index: number) => {
if (colorId) { // should not happen, all indices should have a color defined.
let color = theme.getColor(colorId);
let rgba = color.transparent(0.996);
css += `.monaco-workbench .panel.integrated-terminal .xterm .xterm-color-${index} { color: ${color}; }` +
`.monaco-workbench .panel.integrated-terminal .xterm .xterm-color-${index}::selection { background-color: ${rgba}; }` +
`.monaco-workbench .panel.integrated-terminal .xterm .xterm-bg-color-${index} { background-color: ${color}; }` +
`.monaco-workbench .panel.integrated-terminal .xterm .xterm-bg-color-${index}::selection { color: ${color}; }`;
}
});
this._themeStyleElement.innerHTML = css;
}
/**
* Converts a CSS hex color (#rrggbb) to a CSS rgba color (rgba(r, g, b, a)).
*/
private _convertHexCssColorToRgba(hex: string, alpha: number): string {
let r = parseInt(hex.substr(1, 2), 16);
let g = parseInt(hex.substr(3, 2), 16);
let b = parseInt(hex.substr(5, 2), 16);
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}
private _updateFont(): void {
if (this._terminalService.terminalInstances.length === 0) {
return;
......
/*---------------------------------------------------------------------------------------------
* 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 { Extensions as ThemeingExtensions, IColorRegistry } from 'vs/platform/theme/common/colorRegistry';
import { Registry } from 'vs/platform/platform';
import { ansiColorIdentifiers, registerColors } from 'vs/workbench/parts/terminal/electron-browser/terminalColorRegistry';
import { ITheme, ThemeType } from 'vs/platform/theme/common/themeService';
registerColors();
let themingRegistry = <IColorRegistry>Registry.as(ThemeingExtensions.ColorContribution);
function getMockTheme(type: ThemeType): ITheme {
let theme = {
selector: '',
label: '',
type: type,
getColor: (colorId) => themingRegistry.resolveDefaultColor(colorId, theme),
isDefault: () => true
};
return theme;
}
suite('Workbench - TerminalColorRegistry', () => {
test('hc colors', function () {
let theme = getMockTheme('hc');
let colors = ansiColorIdentifiers.map(colorId => theme.getColor(colorId).toRGBAHex(true));
assert.deepEqual(colors, [
'#000000',
'#cd0000',
'#00cd00',
'#cdcd00',
'#0000ee',
'#cd00cd',
'#00cdcd',
'#e5e5e5',
'#7f7f7f',
'#ff0000',
'#00ff00',
'#ffff00',
'#5c5cff',
'#ff00ff',
'#00ffff',
'#ffffff'
], 'The high contrast terminal colors should be used when the hc theme is active');
});
test('light colors', function () {
let theme = getMockTheme('light');
let colors = ansiColorIdentifiers.map(colorId => theme.getColor(colorId).toRGBAHex(true));
assert.deepEqual(colors, [
'#000000',
'#cd3131',
'#00bc00',
'#949800',
'#0451a5',
'#bc05bc',
'#0598bc',
'#555555',
'#666666',
'#cd3131',
'#14ce14',
'#b5ba00',
'#0451a5',
'#bc05bc',
'#0598bc',
'#a5a5a5'
], 'The light terminal colors should be used when the light theme is active');
});
test('dark colors', function () {
let theme = getMockTheme('dark');
let colors = ansiColorIdentifiers.map(colorId => theme.getColor(colorId).toRGBAHex(true));
assert.deepEqual(colors, [
'#000000',
'#cd3131',
'#0dbc79',
'#e5e510',
'#2472c8',
'#bc3fbc',
'#11a8cd',
'#e5e5e5',
'#666666',
'#f14c4c',
'#23d18b',
'#f5f543',
'#3b8eea',
'#d670d6',
'#29b8db',
'#e5e5e5'
], 'The dark terminal colors should be used when a dark theme is active');
});
});
\ No newline at end of file
......@@ -214,71 +214,5 @@ suite('Workbench - TerminalConfigHelper', () => {
assert.equal(shellConfig.executable, 'foo', 'terminal.integrated.shell.windows should be selected on Windows');
});
test('TerminalConfigHelper - getTheme', function () {
let configurationService: IConfigurationService = new MockConfigurationService();
let configHelper: TerminalConfigHelper;
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService);
configHelper.panelContainer = fixture;
assert.deepEqual(configHelper.getTheme('hc-black'), [
'#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');
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService);
configHelper.panelContainer = fixture;
assert.deepEqual(configHelper.getTheme('vs'), [
'#000000',
'#cd3131',
'#00BC00',
'#949800',
'#0451a5',
'#bc05bc',
'#0598bc',
'#555555',
'#666666',
'#cd3131',
'#14CE14',
'#b5ba00',
'#0451a5',
'#bc05bc',
'#0598bc',
'#a5a5a5'
], 'The light terminal theme should be selected when a vs theme is active');
configHelper = new TerminalConfigHelper(Platform.Linux, configurationService);
configHelper.panelContainer = fixture;
assert.deepEqual(configHelper.getTheme('vs-dark'), [
'#000000',
'#cd3131',
'#0DBC79',
'#e5e510',
'#2472c8',
'#bc3fbc',
'#11a8cd',
'#e5e5e5',
'#666666',
'#f14c4c',
'#23d18b',
'#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
......@@ -7,7 +7,7 @@ import Paths = require('vs/base/common/paths');
import Json = require('vs/base/common/json');
import { Color } from 'vs/base/common/color';
import { ExtensionData, ITokenColorizationRule, IColorTheme, IColorMap, VS_LIGHT_THEME, VS_HC_THEME } from 'vs/workbench/services/themes/common/themeService';
import { convertSettings } from 'vs/workbench/services/themes/electron-browser/stylesContributions';
import { convertSettings } from 'vs/workbench/services/themes/electron-browser/themeCompatibility';
import { TPromise } from 'vs/base/common/winjs.base';
import { getBaseThemeId, getSyntaxThemeId, isDarkTheme, isLightTheme } from 'vs/platform/theme/common/themes';
import nls = require('vs/nls');
......
......@@ -3,15 +3,13 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import nls = require('vs/nls');
import { ITokenColorizationRule, IColorMap } from 'vs/workbench/services/themes/common/themeService';
import { Color } from 'vs/base/common/color';
import * as colorRegistry from 'vs/platform/theme/common/colorRegistry';
import { ITheme, ICssStyleCollector, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import * as editorColorRegistry from 'vs/editor/common/view/editorColorRegistry';
import * as wordHighlighter from 'vs/editor/contrib/wordHighlighter/common/wordHighlighter';
import { ansiColorIdentifiers } from 'vs/workbench/parts/terminal/electron-browser/terminalColorRegistry';
const settingToColorIdMapping: { [settingId: string]: string[] } = {};
......@@ -64,48 +62,12 @@ addSettingMapping('caret', editorColorRegistry.editorCursor);
addSettingMapping('invisibles', editorColorRegistry.editorInvisibles);
addSettingMapping('guide', editorColorRegistry.editorGuide);
const ansiColorMap = ['ansiBlack', 'ansiRed', 'ansiGreen', 'ansiYellow', 'ansiBlue', 'ansiMagenta', 'ansiCyan', 'ansiWhite',
'ansiBrightBlack', 'ansiBrightRed', 'ansiBrightGreen', 'ansiBrightYellow', 'ansiBrightBlue', 'ansiBrightMagenta', 'ansiBrightCyan', 'ansiBrightWhite'
];
const ansiColorMap = {
ansiBlack: 0,
ansiRed: 1,
ansiGreen: 2,
ansiYellow: 3,
ansiBlue: 4,
ansiMagenta: 5,
ansiCyan: 6,
ansiWhite: 7,
ansiBrightBlack: 8,
ansiBrightRed: 9,
ansiBrightGreen: 10,
ansiBrightYellow: 11,
ansiBrightBlue: 12,
ansiBrightMagenta: 13,
ansiBrightCyan: 14,
ansiBrightWhite: 15
};
const keyPrefix = 'terminal';
for (let key in ansiColorMap) {
let id = keyPrefix + key[0].toUpperCase() + key.substr(1);
colorRegistry.registerColor(id, null, nls.localize('terminal.ansiColor', 'Color for terminal {0} color', key));
addSettingMapping(key, id);
}
function updateTerminalStyles(theme: ITheme, collector: ICssStyleCollector) {
for (let key in ansiColorMap) {
let id = keyPrefix + key[0].toUpperCase() + key.substr(1);
const color = theme.getColor(id);
if (color) {
const index = ansiColorMap[key];
const rgba = color.transparent(0.996);
collector.addRule(`.${theme.selector} .panel.integrated-terminal .xterm .xterm-color-${index} { color: ${color}; }`);
collector.addRule(`.${theme.selector} .panel.integrated-terminal .xterm .xterm-color-${index}::selection { background-color: ${rgba}; }`);
collector.addRule(`.${theme.selector} .panel.integrated-terminal .xterm .xterm-bg-color-${index} { background-color: ${color}; }`);
collector.addRule(`.${theme.selector} .panel.integrated-terminal .xterm .xterm-bg-color-${index}::selection { color: ${color}; }`);
};
}
for (let i = 0; i < ansiColorIdentifiers.length; i++) {
addSettingMapping(ansiColorMap[i], ansiColorIdentifiers[i]);
}
registerThemingParticipant(updateTerminalStyles);
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册