提交 891b8c0b 编写于 作者: D Daniel Imms

Integrated terminal prototype

Part of #143
上级 36a964b5
/*---------------------------------------------------------------------------------------------
* 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 {TPromise} from 'vs/base/common/winjs.base';
import {createDecorator, ServiceIdentifier} from 'vs/platform/instantiation/common/instantiation';
export const TERMINAL_PANEL_ID = 'workbench.panel.terminal';
export const TERMINAL_SERVICE_ID = 'terminalService';
export var ITerminalService = createDecorator<ITerminalService>(TERMINAL_SERVICE_ID);
export interface ITerminalService {
serviceId: ServiceIdentifier<any>;
show(): TPromise<any>;
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
.monaco-workbench .integrated-terminal {
align-items: flex-end;
display: flex;
}
.monaco-workbench .integrated-terminal .terminal {
background-color: #1e1e1e!important;
}
.monaco-workbench .terminal-cursor {
background-color: #1e1e1e;
}
.monaco-workbench .reverse-video {
color: #CCC;
}
.vs-dark .monaco-workbench .terminal-cursor {
background-color: #CCC;
}
.vs-dark .monaco-workbench .reverse-video {
color: #252526;
}
/* High Contrast Theming */
.hc-dark .monaco-workbench .integrated-terminal .terminal {
background-color: black!important;
}
.hc-dark .monaco-workbench .terminal-cursor {
background-color: white;
}
.hc-dark .monaco-workbench .reverse-video {
color: black;
}
\ 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.
*--------------------------------------------------------------------------------------------*/
declare module 'pty.js' {
export function fork(file: string, args: string[], options: any): Terminal;
export function spawn(file: string, args: string[], options: any): Terminal;
export function createTerminal(file: string, args: string[], options: any): Terminal;
export interface Terminal {
on(event: string, callback: (data: any) => void): void;
resize(columns: number, rows: number): void;
write(data: string): void;
}
}
\ 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.
*--------------------------------------------------------------------------------------------*/
declare module 'term.js' {
function init(): TermJsTerminal;
// There seems to be no way to export this so it can be referenced outside of this file when a
// module is a function.
interface TermJsTerminal {
on(event: string, callback: (data: any) => void): void;
resize(columns: number, rows: number): void;
}
export = init;
}
\ 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.
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/terminal.contribution';
import nls = require('vs/nls');
//import {KeyMod, KeyCode} from 'vs/base/common/keyCodes';
import {SyncActionDescriptor} from 'vs/platform/actions/common/actions';
import {registerSingleton} from 'vs/platform/instantiation/common/extensions';
import {IWorkbenchActionRegistry, Extensions as ActionExtensions} from 'vs/workbench/common/actionRegistry';
import {TerminalService} from 'vs/workbench/parts/terminal/node/terminalService';
import {ToggleTerminalAction} from 'vs/workbench/parts/terminal/node/terminalActions';
import {ITerminalService, TERMINAL_PANEL_ID} from 'vs/workbench/parts/terminal/common/terminal';
import * as panel from 'vs/workbench/browser/panel';
import {Registry} from 'vs/platform/platform';
import {Extensions, IConfigurationRegistry} from 'vs/platform/configuration/common/configurationRegistry';
let configurationRegistry = <IConfigurationRegistry>Registry.as(Extensions.Configuration);
configurationRegistry.registerConfiguration({
'id': 'terminal',
'order': 100,
'title': nls.localize('integratedTerminalConfigurationTitle', "Integrated terminal configuration"),
'type': 'object',
'properties': {
'terminal.integrated.enabled': {
'description': nls.localize('terminal.integrated.enabled', "(Experimental) Enable the integrated terminal."),
'type': 'boolean',
'default': false
}
}
});
// Register Service
registerSingleton(ITerminalService, TerminalService);
// Register Output Panel
(<panel.PanelRegistry>Registry.as(panel.Extensions.Panels)).registerPanel(new panel.PanelDescriptor(
'vs/workbench/parts/terminal/node/terminalPanel',
'TerminalPanel',
TERMINAL_PANEL_ID,
nls.localize('terminal', "Terminal"),
'terminal'
));
// register toggle output action globally
let actionRegistry = <IWorkbenchActionRegistry>Registry.as(ActionExtensions.WorkbenchActions);
/*actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleTerminalAction, ToggleTerminalAction.ID, ToggleTerminalAction.LABEL, {
primary: KeyMod.CtrlCmd | KeyCode.US_BACKTICK
}), nls.localize('viewCategory', "View"));*/
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ToggleTerminalAction, ToggleTerminalAction.ID, ToggleTerminalAction.LABEL), nls.localize('viewCategory', "View"));
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import {TPromise} from 'vs/base/common/winjs.base';
import nls = require('vs/nls');
import {Action} from 'vs/base/common/actions';
import {IPartService} from 'vs/workbench/services/part/common/partService';
import {IPanelService} from 'vs/workbench/services/panel/common/panelService';
import {TERMINAL_PANEL_ID, ITerminalService} from 'vs/workbench/parts/terminal/common/terminal';
export class ToggleTerminalAction extends Action {
public static ID = 'workbench.action.terminal.toggleTerminal';
public static LABEL = nls.localize('toggleTerminal', "Toggle Terminal");
constructor(
id: string, label: string,
@IPartService private partService: IPartService,
@IPanelService private panelService: IPanelService,
@ITerminalService private terminalService: ITerminalService
) {
super(id, label);
}
public run(event?: any): TPromise<any> {
const panel = this.panelService.getActivePanel();
if (panel && panel.getId() === TERMINAL_PANEL_ID) {
this.partService.setPanelHidden(true);
return TPromise.as(null);
}
return this.terminalService.show();
}
}
\ 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.
*--------------------------------------------------------------------------------------------*/
import termJs = require('term.js');
import fs = require('fs');
import {fork, Terminal} from 'pty.js';
import {TPromise} from 'vs/base/common/winjs.base';
import {Builder, Dimension} from 'vs/base/browser/builder';
import {ITelemetryService} from 'vs/platform/telemetry/common/telemetry';
import {TERMINAL_PANEL_ID} from 'vs/workbench/parts/terminal/common/terminal';
import {Panel} from 'vs/workbench/browser/panel';
import {ScrollableElement} from 'vs/base/browser/ui/scrollbar/scrollableElementImpl';
import {DomNodeScrollable} from 'vs/base/browser/ui/scrollbar/domNodeScrollable';
const TERMINAL_CHAR_WIDTH = 8;
const TERMINAL_CHAR_HEIGHT = 18;
export class TerminalPanel extends Panel {
private ptyProcess: Terminal;
private parentDomElement: HTMLElement;
private terminal;
private terminalDomElement: HTMLDivElement;
constructor(
@ITelemetryService telemetryService: ITelemetryService
) {
super(TERMINAL_PANEL_ID, telemetryService);
}
public layout(dimension: Dimension): void {
let cols = Math.floor(this.parentDomElement.offsetWidth / TERMINAL_CHAR_WIDTH);
let rows = Math.floor(this.parentDomElement.offsetHeight / TERMINAL_CHAR_HEIGHT);
this.terminal.resize(cols, rows);
this.ptyProcess.resize(cols, rows);
}
public create(parent: Builder): TPromise<void> {
super.create(parent);
this.ptyProcess = fork(process.env.SHELL || 'sh', [], {
name: fs.existsSync('/usr/share/terminfo/x/xterm-256color') ? 'xterm-256color' : 'xterm',
cols: 80,
rows: 6,
cwd: process.env.HOME
});
this.parentDomElement = parent.getHTMLElement();
this.terminalDomElement = document.createElement('div');
this.parentDomElement.classList.add('integrated-terminal');
let terminalScrollable = new DomNodeScrollable(this.terminalDomElement);
let terminalContainer = new ScrollableElement(this.terminalDomElement, terminalScrollable, { horizontal: 'hidden', vertical: 'auto' });
this.terminal = termJs();
this.ptyProcess.on('data', (data) => {
this.terminal.write(data);
});
this.terminal.on('data', (data) => {
this.ptyProcess.write(data);
return false;
});
this.terminal.open(this.terminalDomElement);
this.parentDomElement.appendChild(terminalContainer.getDomNode());
this.terminalDomElement.style.fontFamily = 'Hack, mono';
this.terminal.colors = [
'#000000', // black
'#cd3131', // red
'#09885a', // green
'#e5e510', // yellow
'#0451a5', // blue
'#bc05bc', // magenta
'#0598bc', // cyan
'#e5e5e5', // white
'#111111', // bright black
'#dc6f6f', // bright red
'#53ac8c', // bright green
'#eded58', // bright yellow
'#4f85c0', // bright blue
'#d050d0', // bright magenta
'#50b7d0', // bright cyan
'#FFFFFF', // bright white
];
return TPromise.as(null);
}
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import {TPromise} from 'vs/base/common/winjs.base';
import {IPanelService} from 'vs/workbench/services/panel/common/panelService';
import {ITerminalService, TERMINAL_PANEL_ID} from 'vs/workbench/parts/terminal/common/terminal';
export class TerminalService implements ITerminalService {
public serviceId = ITerminalService;
constructor(
@IPanelService private panelService: IPanelService
) {
}
public show(): TPromise<any> {
return this.panelService.openPanel(TERMINAL_PANEL_ID, true);
}
}
\ No newline at end of file
......@@ -58,6 +58,8 @@ define([
'vs/workbench/parts/output/browser/output.contribution',
'vs/workbench/parts/terminal/node/terminal.contribution',
'vs/workbench/parts/markdown/browser/markdown.contribution',
'vs/workbench/parts/markdown/browser/markdownActions.contribution',
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册