提交 7b21a5c9 编写于 作者: D Daniel Imms

Merge pull request #7288 from Microsoft/tyriar/xtermjs_terminal

Tyriar/xtermjs terminal
......@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'term.js' {
declare module 'xterm' {
function init(options: any): TermJsTerminal;
// There seems to be no way to export this so it can be referenced outside of this file when a
......
......@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import cp = require('child_process');
import termJs = require('term.js');
import xterm = require('xterm');
import lifecycle = require('vs/base/common/lifecycle');
import os = require('os');
import path = require('path');
......@@ -25,6 +25,7 @@ export class TerminalInstance {
private ptyProcess: cp.ChildProcess;
private terminal;
private terminalDomElement: HTMLDivElement;
private wrapperElement: HTMLDivElement;
private font: ITerminalFont;
public constructor(
......@@ -35,7 +36,7 @@ export class TerminalInstance {
private onExitCallback: (TerminalInstance) => void
) {
this.toDispose = [];
this.parentDomElement.innerHTML = '';
this.wrapperElement = document.createElement('div');
this.ptyProcess = this.createTerminalProcess();
this.terminalDomElement = document.createElement('div');
this.parentDomElement.classList.add('integrated-terminal');
......@@ -45,7 +46,7 @@ export class TerminalInstance {
vertical: ScrollbarVisibility.Auto
});
this.toDispose.push(terminalScrollbar);
this.terminal = termJs({
this.terminal = xterm({
cursorBlink: false // term.js' blinking cursor breaks selection
});
......@@ -89,15 +90,16 @@ export class TerminalInstance {
}));
this.terminal.open(this.terminalDomElement);
this.parentDomElement.appendChild(terminalScrollbar.getDomNode());
this.wrapperElement.appendChild(terminalScrollbar.getDomNode());
this.parentDomElement.appendChild(this.wrapperElement);
}
public layout(dimension: Dimension): void {
if (!this.font || !this.font.charWidth || !this.font.charHeight) {
return;
}
let cols = Math.floor(this.parentDomElement.offsetWidth / this.font.charWidth);
let rows = Math.floor(this.parentDomElement.offsetHeight / this.font.charHeight);
let cols = Math.floor(dimension.width / this.font.charWidth);
let rows = Math.floor(dimension.height / this.font.charHeight);
if (this.terminal) {
this.terminal.resize(cols, rows);
}
......@@ -131,14 +133,6 @@ export class TerminalInstance {
});
}
public setTheme(colors: string[]): void {
if (!this.terminal) {
return;
}
this.terminal.colors = colors;
this.terminal.refresh(0, this.terminal.rows);
}
public setFont(font: ITerminalFont): void {
this.font = font;
this.terminalDomElement.style.fontFamily = this.font.fontFamily;
......@@ -160,6 +154,8 @@ export class TerminalInstance {
}
public dispose(): void {
this.parentDomElement.removeChild(this.wrapperElement);
this.wrapperElement = null;
this.toDispose = lifecycle.dispose(this.toDispose);
this.terminal.destroy();
this.ptyProcess.kill();
......
......@@ -20,6 +20,7 @@ export class TerminalPanel extends Panel {
private toDispose: lifecycle.IDisposable[];
private parentDomElement: HTMLElement;
private themeStyleElement: HTMLElement;
private configurationHelper: TerminalConfigHelper;
private terminalInstance: TerminalInstance;
......@@ -43,6 +44,8 @@ export class TerminalPanel extends Panel {
public create(parent: Builder): TPromise<void> {
super.create(parent);
this.parentDomElement = parent.getHTMLElement();
this.themeStyleElement = document.createElement('style');
this.parentDomElement.appendChild(this.themeStyleElement);
this.configurationHelper = new TerminalConfigHelper(platform.platform, this.configurationService, this.parentDomElement);
return this.createTerminal();
......@@ -88,7 +91,29 @@ export class TerminalPanel extends Panel {
if (!themeId) {
themeId = this.themeService.getTheme();
}
this.terminalInstance.setTheme(this.configurationHelper.getTheme(themeId));
let theme = this.configurationHelper.getTheme(themeId);
let css = '';
theme.forEach((color: string, index: number) => {
// TODO: The classes could probably be reduced, it's so long to beat the specificity of the general rule.
let rgba = this.convertHexCssColorToRgba(color, 0.996);
css += `.monaco-workbench .integrated-terminal .terminal .xterm-color-${index} { color: ${color}; }` +
`.monaco-workbench .integrated-terminal .terminal .xterm-color-${index}::selection { background-color: ${rgba}; }` +
`.monaco-workbench .integrated-terminal .terminal .xterm-bg-color-${index} { background-color: ${color}; }` +
`.monaco-workbench .integrated-terminal .terminal .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 {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册