mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Merge branch 'master' into master
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
"project": [
|
||||
"src/browser/tsconfig.json",
|
||||
"src/common/tsconfig.json",
|
||||
"src/headless/tsconfig.json",
|
||||
"test/api/tsconfig.json",
|
||||
"test/benchmark/tsconfig.json",
|
||||
"addons/xterm-addon-attach/src/tsconfig.json",
|
||||
|
||||
@@ -162,20 +162,23 @@ Xterm.js is used in several world-class applications to provide great terminal e
|
||||
- [**CoCalc**](https://cocalc.com/): Lots of free software pre-installed, to chat, collaborate, develop, program, publish, research, share, teach, in C++, HTML, Julia, Jupyter, LaTeX, Markdown, Python, R, SageMath, Scala, ...
|
||||
- [**Dank Domain**](https://www.DDgame.us/): Open source multiuser medieval game supporting old & new terminal emulation.
|
||||
- [**DockerStacks**](https://docker-stacks.com/): Local LAMP/LEMP development studio
|
||||
- [**Codecademy**](https://codecademy.com/): Uses xterm.js in its courses on Bash.
|
||||
- [**Codecademy**](https://codecademy.com/): Uses xterm.js in its courses on Bash.
|
||||
- [**Laravel Ssh Web Client**](https://github.com/roke22/Laravel-ssh-client): Laravel server inventory with ssh web client to connect at server using xterm.js
|
||||
- [**Repl.it**](https://repl.it): Collaborative browser based IDE with support for 50+ different languages.
|
||||
- [**TeleType**](https://github.com/akshaykmr/TeleType): cli tool that allows you to share your terminal online conveniently. Show off mad cli-fu, help a colleague, teach, or troubleshoot.
|
||||
- [**Intervue**](https://www.intervue.io): Pair programming for interviews. Multiple programming languages are supported, with results displayed by xterm.js.
|
||||
- [**TRASA**](https://trasa.io): Zero trust access to Web, SSH, RDP, and Database services.
|
||||
- [**TRASA**](https://trasa.io): Zero trust access to Web, SSH, RDP, and Database services.
|
||||
- [**Commas**](https://github.com/CyanSalt/commas): Commas is a hackable terminal and command runner.
|
||||
- [**Devtron**](https://github.com/devtron-labs/devtron): Software Delivery Workflow For Kubernetes.
|
||||
- [**Devtron**](https://github.com/devtron-labs/devtron): Software Delivery Workflow For Kubernetes.
|
||||
- [**NxShell**](https://github.com/nxshell/nxshell): An easy to use new terminal for SSH.
|
||||
- [**gifcast**](https://dstein64.github.io/gifcast/): Converts an asciinema cast to an animated GIF.
|
||||
- [**WizardWebssh**](https://gitlab.com/mikeramsey/wizardwebssh): A terminal with Pyqt5 Widget for embedding, which can be used as an ssh client to connect to your ssh servers. It is written in Python, based on tornado, paramiko, and xterm.js.
|
||||
- [**Wizard Assistant**](https://wizardassistant.com/): Wizard Assistant comes with advanced automation tools, preloaded common and special time-saving commands, and a built-in SSH terminal. Now you can remotely administer, troubleshoot, and analyze any system with ease.
|
||||
- [**Wizard Assistant**](https://wizardassistant.com/): Wizard Assistant comes with advanced automation tools, preloaded common and special time-saving commands, and a built-in SSH terminal. Now you can remotely administer, troubleshoot, and analyze any system with ease.
|
||||
- [**ucli**](https://github.com/tsadarsh/ucli): Command Line for everyone :family_man_woman_girl_boy: at [www.ucli.tech](https://www.ucli.tech).
|
||||
- [**Tess**](https://github.com/SquitchYT/Tess/): Simple Terminal Fully Customizable for Everyone.
|
||||
- [**HashiCorp Nomad**](https://www.nomadproject.io/): A container orchestrator with the ability to connect to remote tasks via a web interface using websockets and xterm.js.
|
||||
- [**TermPair**](https://github.com/cs01/termpair): View and control terminals from your browser with end-to-end encryption
|
||||
- [**gdbgui**](https://github.com/cs01/gdbgui): Browser-based frontend to gdb (gnu debugger)
|
||||
- [And much more...](https://github.com/xtermjs/xterm.js/network/dependents)
|
||||
|
||||
Do you use xterm.js in your application as well? Please [open a Pull Request](https://github.com/sourcelair/xterm.js/pulls) to include it here. We would love to have it on our list. Note: Please add any new contributions to the end of the list only.
|
||||
|
||||
@@ -23,7 +23,7 @@ export interface ISearchResult {
|
||||
row: number;
|
||||
}
|
||||
|
||||
const NON_WORD_CHARACTERS = ' ~!@#$%^&*()+`-=[]{}|\;:"\',./<>?';
|
||||
const NON_WORD_CHARACTERS = ' ~!@#$%^&*()+`-=[]{}|\\;:"\',./<>?';
|
||||
const LINES_CACHE_TIME_TO_LIVE = 15 * 1000; // 15 secs
|
||||
|
||||
export class SearchAddon implements ITerminalAddon {
|
||||
|
||||
@@ -164,5 +164,9 @@ jobs:
|
||||
displayName: Cache node modules
|
||||
- script: yarn --frozen-lockfile
|
||||
displayName: 'Install dependencies and build'
|
||||
- script: |
|
||||
yarn package-headless
|
||||
node ./bin/package_headless.js
|
||||
displayName: 'Package xterm-headless'
|
||||
- script: NPM_AUTH_TOKEN="$(NPM_AUTH_TOKEN)" node ./bin/publish.js
|
||||
displayName: 'Package and publish to npm'
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Copyright (c) 2021 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
const { exec } = require('child_process');
|
||||
const fs = require('fs');
|
||||
const { join } = require('path');
|
||||
|
||||
const repoRoot = join(__dirname, '..');
|
||||
const headlessRoot = join(repoRoot, 'headless');
|
||||
|
||||
console.log('> headless/package.json');
|
||||
const xtermPackageJson = require('../package.json');
|
||||
const xtermHeadlessPackageJson = {
|
||||
...xtermPackageJson,
|
||||
name: 'xterm-headless',
|
||||
description: 'A headless terminal component that runs in Node.js',
|
||||
main: 'lib-headless/xterm-headless.js',
|
||||
types: 'typings/xterm-headless.d.ts',
|
||||
};
|
||||
delete xtermHeadlessPackageJson['scripts'];
|
||||
delete xtermHeadlessPackageJson['devDependencies'];
|
||||
delete xtermHeadlessPackageJson['style'];
|
||||
fs.writeFileSync(join(headlessRoot, 'package.json'), JSON.stringify(xtermHeadlessPackageJson, null, 1));
|
||||
console.log(fs.readFileSync(join(headlessRoot, 'package.json')).toString());
|
||||
|
||||
console.log('> headless/typings/');
|
||||
mkdirF(join(headlessRoot, 'typings'));
|
||||
fs.copyFileSync(
|
||||
join(repoRoot, 'typings/xterm-headless.d.ts'),
|
||||
join(headlessRoot, 'typings/xterm-headless.d.ts')
|
||||
);
|
||||
|
||||
console.log('> headless/logo-full.png');
|
||||
fs.copyFileSync(
|
||||
join(repoRoot, 'logo-full.png'),
|
||||
join(headlessRoot, 'logo-full.png')
|
||||
);
|
||||
|
||||
function mkdirF(p) {
|
||||
if (!fs.existsSync(p)) {
|
||||
fs.mkdirSync(p);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('> Publish dry run');
|
||||
exec('npm publish --dry-run', { cwd: headlessRoot }, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
console.log(`error: ${error.message}`);
|
||||
return;
|
||||
}
|
||||
if (stderr) {
|
||||
console.error(`stderr:\n${stderr}`);
|
||||
}
|
||||
console.log(`stdout:\n${stdout}`);
|
||||
});
|
||||
@@ -22,6 +22,7 @@ const changedFiles = getChangedFilesInCommit('HEAD');
|
||||
let isStableRelease = false;
|
||||
if (changedFiles.some(e => e.search(/^addons\//) === -1)) {
|
||||
isStableRelease = checkAndPublishPackage(path.resolve(__dirname, '..'));
|
||||
checkAndPublishPackage(path.resolve(__dirname, '../headless'));
|
||||
}
|
||||
|
||||
// Publish addons if any files were changed inside of the addon
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
lib-headless/
|
||||
typings/
|
||||
logo-full.png
|
||||
./package.json
|
||||
@@ -0,0 +1,6 @@
|
||||
# Include
|
||||
!typings/*.d.ts
|
||||
!lib-headless/
|
||||
|
||||
# Exclude
|
||||
test/
|
||||
@@ -0,0 +1,31 @@
|
||||
# [](https://xtermjs.org)
|
||||
|
||||
⚠ This package is experimental
|
||||
|
||||
`xterm-headless` is a headless terminal that can be run in node.js. This is useful in combination with the frontend [`xterm`](https://www.npmjs.com/package/xterm) for example to keep track of a terminal's state on a remote server where the process is hosted.
|
||||
|
||||
## Getting Started
|
||||
|
||||
First, you need to install the module, we ship exclusively through npm, so you need that installed and then add xterm.js as a dependency by running:
|
||||
|
||||
```sh
|
||||
npm install xterm-headless
|
||||
```
|
||||
|
||||
Then import as you would a regular node package. The recommended way to load `xterm-headless` is with TypeScript and the ES6 module syntax:
|
||||
|
||||
```javascript
|
||||
import { Terminal } from 'xterm-headless';
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
The full API for `xterm-headless` is contained within the [TypeScript declaration file](https://github.com/xtermjs/xterm.js/blob/master/typings/xterm-headless.d.ts), use the branch/tag picker in GitHub (`w`) to navigate to the correct version of the API.
|
||||
|
||||
Note that some APIs are marked *experimental*, these are added to enable experimentation with new ideas without committing to support it like a normal [semver](https://semver.org/) API. Note that these APIs can change radically between versions, so be sure to read release notes if you plan on using experimental APIs.
|
||||
|
||||
### Addons
|
||||
|
||||
Addons in `xterm-headless` work the [same as in `xterm`](https://github.com/xtermjs/xterm.js/blob/master/README.md#addons) with the one caveat being that the addon needs to be packaged for node.js and not use any DOM APIs.
|
||||
|
||||
Currently no official addons are packaged on npm.
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "xterm-headless",
|
||||
"description": "A headless terminal component that runs in Node.js",
|
||||
"version": "4.13.0-alpha3",
|
||||
"main": "lib-headless/xterm-headless.js",
|
||||
"types": "typings/xterm-headless.d.ts",
|
||||
"repository": "https://github.com/xtermjs/xterm.js",
|
||||
"license": "MIT"
|
||||
}
|
||||
@@ -10,6 +10,8 @@
|
||||
"scripts": {
|
||||
"prepackage": "npm run build",
|
||||
"package": "webpack",
|
||||
"package-headless": "webpack --config ./webpack.config.headless.js",
|
||||
"postpackage-headless": "node ./bin/package_headless.js",
|
||||
"start": "node demo/start",
|
||||
"start-debug": "node --inspect-brk demo/start",
|
||||
"lint": "eslint -c .eslintrc.json --max-warnings 0 --ext .ts src/ addons/",
|
||||
|
||||
@@ -113,8 +113,8 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
||||
public get onSelectionChange(): IEvent<void> { return this._onSelectionChange.event; }
|
||||
private _onTitleChange = new EventEmitter<string>();
|
||||
public get onTitleChange(): IEvent<string> { return this._onTitleChange.event; }
|
||||
private _onBell = new EventEmitter<void>();
|
||||
public get onBell (): IEvent<void> { return this._onBell.event; }
|
||||
private _onBell = new EventEmitter<void>();
|
||||
public get onBell(): IEvent<void> { return this._onBell.event; }
|
||||
|
||||
private _onFocus = new EventEmitter<void>();
|
||||
public get onFocus(): IEvent<void> { return this._onFocus.event; }
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
|
||||
import { Terminal as ITerminalApi, ITerminalOptions, IMarker, IDisposable, ILinkMatcherOptions, ITheme, ILocalizableStrings, ITerminalAddon, ISelectionPosition, IBufferNamespace as IBufferNamespaceApi, IParser, ILinkProvider, IUnicodeHandling, FontWeight } from 'xterm';
|
||||
import { ITerminal } from 'browser/Types';
|
||||
import { Terminal as TerminalCore } from '../Terminal';
|
||||
import * as Strings from '../LocalizableStrings';
|
||||
import { Terminal as TerminalCore } from 'browser/Terminal';
|
||||
import * as Strings from 'browser/LocalizableStrings';
|
||||
import { IEvent } from 'common/EventEmitter';
|
||||
import { ParserApi } from 'common/public/ParserApi';
|
||||
import { UnicodeApi } from 'common/public/UnicodeApi';
|
||||
import { AddonManager } from './AddonManager';
|
||||
import { AddonManager } from 'common/public/AddonManager';
|
||||
import { BufferNamespaceApi } from 'common/public/BufferNamespaceApi';
|
||||
|
||||
export class Terminal implements ITerminalApi {
|
||||
@@ -30,17 +30,17 @@ export class Terminal implements ITerminalApi {
|
||||
}
|
||||
}
|
||||
|
||||
public get onCursorMove(): IEvent<void> { return this._core.onCursorMove; }
|
||||
public get onLineFeed(): IEvent<void> { return this._core.onLineFeed; }
|
||||
public get onSelectionChange(): IEvent<void> { return this._core.onSelectionChange; }
|
||||
public get onData(): IEvent<string> { return this._core.onData; }
|
||||
public get onBinary(): IEvent<string> { return this._core.onBinary; }
|
||||
public get onTitleChange(): IEvent<string> { return this._core.onTitleChange; }
|
||||
public get onBell(): IEvent<void> { return this._core.onBell; }
|
||||
public get onScroll(): IEvent<number> { return this._core.onScroll; }
|
||||
public get onBinary(): IEvent<string> { return this._core.onBinary; }
|
||||
public get onCursorMove(): IEvent<void> { return this._core.onCursorMove; }
|
||||
public get onData(): IEvent<string> { return this._core.onData; }
|
||||
public get onKey(): IEvent<{ key: string, domEvent: KeyboardEvent }> { return this._core.onKey; }
|
||||
public get onLineFeed(): IEvent<void> { return this._core.onLineFeed; }
|
||||
public get onRender(): IEvent<{ start: number, end: number }> { return this._core.onRender; }
|
||||
public get onResize(): IEvent<{ cols: number, rows: number }> { return this._core.onResize; }
|
||||
public get onScroll(): IEvent<number> { return this._core.onScroll; }
|
||||
public get onSelectionChange(): IEvent<void> { return this._core.onSelectionChange; }
|
||||
public get onTitleChange(): IEvent<string> { return this._core.onTitleChange; }
|
||||
|
||||
public get element(): HTMLElement | undefined { return this._core.element; }
|
||||
public get parser(): IParser {
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
/**
|
||||
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
|
||||
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
|
||||
* @license MIT
|
||||
*
|
||||
* Originally forked from (with the author's permission):
|
||||
* Fabrice Bellard's javascript vt100 for jslinux:
|
||||
* http://bellard.org/jslinux/
|
||||
* Copyright (c) 2011 Fabrice Bellard
|
||||
* The original design remains. The terminal itself
|
||||
* has been extended to include xterm CSI codes, among
|
||||
* other features.
|
||||
*
|
||||
* Terminal Emulation References:
|
||||
* http://vt100.net/
|
||||
* http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt
|
||||
* http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
|
||||
* http://invisible-island.net/vttest/
|
||||
* http://www.inwap.com/pdp10/ansicode.txt
|
||||
* http://linux.die.net/man/4/console_codes
|
||||
* http://linux.die.net/man/7/urxvt
|
||||
*/
|
||||
|
||||
import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine';
|
||||
import { IBuffer } from 'common/buffer/Types';
|
||||
import { CoreTerminal } from 'common/CoreTerminal';
|
||||
import { EventEmitter, forwardEvent, IEvent } from 'common/EventEmitter';
|
||||
import { ITerminalOptions as IInitializedTerminalOptions } from 'common/services/Services';
|
||||
import { IMarker, ITerminalOptions, ScrollSource } from 'common/Types';
|
||||
|
||||
export class Terminal extends CoreTerminal {
|
||||
// TODO: We should remove options once components adopt optionsService
|
||||
public get options(): IInitializedTerminalOptions { return this.optionsService.options; }
|
||||
|
||||
private _onBell = new EventEmitter<void>();
|
||||
public get onBell(): IEvent<void> { return this._onBell.event; }
|
||||
private _onCursorMove = new EventEmitter<void>();
|
||||
public get onCursorMove(): IEvent<void> { return this._onCursorMove.event; }
|
||||
private _onTitleChange = new EventEmitter<string>();
|
||||
public get onTitleChange(): IEvent<string> { return this._onTitleChange.event; }
|
||||
|
||||
private _onA11yCharEmitter = new EventEmitter<string>();
|
||||
public get onA11yChar(): IEvent<string> { return this._onA11yCharEmitter.event; }
|
||||
private _onA11yTabEmitter = new EventEmitter<number>();
|
||||
public get onA11yTab(): IEvent<number> { return this._onA11yTabEmitter.event; }
|
||||
|
||||
/**
|
||||
* Creates a new `Terminal` object.
|
||||
*
|
||||
* @param options An object containing a set of options, the available options are:
|
||||
* - `cursorBlink` (boolean): Whether the terminal cursor blinks
|
||||
* - `cols` (number): The number of columns of the terminal (horizontal size)
|
||||
* - `rows` (number): The number of rows of the terminal (vertical size)
|
||||
*
|
||||
* @public
|
||||
* @class Xterm Xterm
|
||||
* @alias module:xterm/src/xterm
|
||||
*/
|
||||
constructor(
|
||||
options: ITerminalOptions = {}
|
||||
) {
|
||||
super(options);
|
||||
|
||||
this._setup();
|
||||
|
||||
// Setup InputHandler listeners
|
||||
this.register(this._inputHandler.onRequestBell(() => this.bell()));
|
||||
this.register(this._inputHandler.onRequestReset(() => this.reset()));
|
||||
this.register(forwardEvent(this._inputHandler.onCursorMove, this._onCursorMove));
|
||||
this.register(forwardEvent(this._inputHandler.onTitleChange, this._onTitleChange));
|
||||
this.register(forwardEvent(this._inputHandler.onA11yChar, this._onA11yCharEmitter));
|
||||
this.register(forwardEvent(this._inputHandler.onA11yTab, this._onA11yTabEmitter));
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
if (this._isDisposed) {
|
||||
return;
|
||||
}
|
||||
super.dispose();
|
||||
this.write = () => { };
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience property to active buffer.
|
||||
*/
|
||||
public get buffer(): IBuffer {
|
||||
return this.buffers.active;
|
||||
}
|
||||
|
||||
protected _updateOptions(key: string): void {
|
||||
super._updateOptions(key);
|
||||
|
||||
// TODO: These listeners should be owned by individual components
|
||||
switch (key) {
|
||||
case 'tabStopWidth': this.buffers.setupTabStops(); break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Support paste here?
|
||||
|
||||
public get markers(): IMarker[] {
|
||||
return this.buffer.markers;
|
||||
}
|
||||
|
||||
public addMarker(cursorYOffset: number): IMarker | undefined {
|
||||
// Disallow markers on the alt buffer
|
||||
if (this.buffer !== this.buffers.normal) {
|
||||
return;
|
||||
}
|
||||
|
||||
return this.buffer.addMarker(this.buffer.ybase + this.buffer.y + cursorYOffset);
|
||||
}
|
||||
|
||||
public bell(): void {
|
||||
this._onBell.fire();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resizes the terminal.
|
||||
*
|
||||
* @param x The number of columns to resize to.
|
||||
* @param y The number of rows to resize to.
|
||||
*/
|
||||
public resize(x: number, y: number): void {
|
||||
if (x === this.cols && y === this.rows) {
|
||||
return;
|
||||
}
|
||||
|
||||
super.resize(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the entire buffer, making the prompt line the new first line.
|
||||
*/
|
||||
public clear(): void {
|
||||
if (this.buffer.ybase === 0 && this.buffer.y === 0) {
|
||||
// Don't clear if it's already clear
|
||||
return;
|
||||
}
|
||||
this.buffer.lines.set(0, this.buffer.lines.get(this.buffer.ybase + this.buffer.y)!);
|
||||
this.buffer.lines.length = 1;
|
||||
this.buffer.ydisp = 0;
|
||||
this.buffer.ybase = 0;
|
||||
this.buffer.y = 0;
|
||||
for (let i = 1; i < this.rows; i++) {
|
||||
this.buffer.lines.push(this.buffer.getBlankLine(DEFAULT_ATTR_DATA));
|
||||
}
|
||||
this._onScroll.fire({ position: this.buffer.ydisp, source: ScrollSource.TERMINAL });
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset terminal.
|
||||
* Note: Calling this directly from JS is synchronous but does not clear
|
||||
* input buffers and does not reset the parser, thus the terminal will
|
||||
* continue to apply pending input data.
|
||||
* If you need in band reset (synchronous with input data) consider
|
||||
* using DECSTR (soft reset, CSI ! p) or RIS instead (hard reset, ESC c).
|
||||
*/
|
||||
public reset(): void {
|
||||
/**
|
||||
* Since _setup handles a full terminal creation, we have to carry forward
|
||||
* a few things that should not reset.
|
||||
*/
|
||||
this.options.rows = this.rows;
|
||||
this.options.cols = this.cols;
|
||||
|
||||
this._setup();
|
||||
super.reset();
|
||||
}
|
||||
}
|
||||
Vendored
+31
@@ -0,0 +1,31 @@
|
||||
import { IBuffer, IBufferSet } from 'common/buffer/Types';
|
||||
import { IEvent } from 'common/EventEmitter';
|
||||
import { IFunctionIdentifier, IParams } from 'common/parser/Types';
|
||||
import { ICoreTerminal, IDisposable, IMarker, ITerminalOptions } from 'common/Types';
|
||||
|
||||
export interface ITerminal extends ICoreTerminal {
|
||||
rows: number;
|
||||
cols: number;
|
||||
buffer: IBuffer;
|
||||
buffers: IBufferSet;
|
||||
markers: IMarker[];
|
||||
// TODO: We should remove options once components adopt optionsService
|
||||
options: ITerminalOptions;
|
||||
|
||||
onCursorMove: IEvent<void>;
|
||||
onData: IEvent<string>;
|
||||
onBinary: IEvent<string>;
|
||||
onLineFeed: IEvent<void>;
|
||||
onResize: IEvent<{ cols: number, rows: number }>;
|
||||
onTitleChange: IEvent<string>;
|
||||
resize(columns: number, rows: number): void;
|
||||
addCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean): IDisposable;
|
||||
addDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: IParams) => boolean): IDisposable;
|
||||
addEscHandler(id: IFunctionIdentifier, callback: () => boolean): IDisposable;
|
||||
addOscHandler(ident: number, callback: (data: string) => boolean): IDisposable;
|
||||
addMarker(cursorYOffset: number): IMarker | undefined;
|
||||
dispose(): void;
|
||||
clear(): void;
|
||||
write(data: string | Uint8Array, callback?: () => void): void;
|
||||
reset(): void;
|
||||
}
|
||||
@@ -0,0 +1,386 @@
|
||||
/**
|
||||
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { deepStrictEqual, strictEqual, throws } from 'assert';
|
||||
import { Terminal } from 'headless/public/Terminal';
|
||||
|
||||
let term: Terminal;
|
||||
|
||||
describe('Headless API Tests', function(): void {
|
||||
beforeEach(() => {
|
||||
// Create default terminal to be used by most tests
|
||||
term = new Terminal();
|
||||
});
|
||||
|
||||
it('Default options', async () => {
|
||||
strictEqual(term.cols, 80);
|
||||
strictEqual(term.rows, 24);
|
||||
});
|
||||
|
||||
it('Proposed API check', async () => {
|
||||
term = new Terminal({ allowProposedApi: false });
|
||||
throws(() => term.buffer, (error) => error.message === 'You must set the allowProposedApi option to true to use proposed API');
|
||||
});
|
||||
|
||||
it('write', async () => {
|
||||
await writeSync('foo');
|
||||
await writeSync('bar');
|
||||
await writeSync('文');
|
||||
lineEquals(0, 'foobar文');
|
||||
});
|
||||
|
||||
it('write with callback', async () => {
|
||||
let result: string | undefined;
|
||||
await new Promise<void>(r => {
|
||||
term.write('foo', () => { result = 'a'; });
|
||||
term.write('bar', () => { result += 'b'; });
|
||||
term.write('文', () => {
|
||||
result += 'c';
|
||||
r();
|
||||
});
|
||||
});
|
||||
lineEquals(0, 'foobar文');
|
||||
strictEqual(result, 'abc');
|
||||
});
|
||||
|
||||
it('write - bytes (UTF8)', async () => {
|
||||
await writeSync(new Uint8Array([102, 111, 111])); // foo
|
||||
await writeSync(new Uint8Array([98, 97, 114])); // bar
|
||||
await writeSync(new Uint8Array([230, 150, 135])); // 文
|
||||
lineEquals(0, 'foobar文');
|
||||
});
|
||||
|
||||
it('write - bytes (UTF8) with callback', async () => {
|
||||
let result: string | undefined;
|
||||
await new Promise<void>(r => {
|
||||
term.write(new Uint8Array([102, 111, 111]), () => { result = 'A'; }); // foo
|
||||
term.write(new Uint8Array([98, 97, 114]), () => { result += 'B'; }); // bar
|
||||
term.write(new Uint8Array([230, 150, 135]), () => { // 文
|
||||
result += 'C';
|
||||
r();
|
||||
});
|
||||
});
|
||||
lineEquals(0, 'foobar文');
|
||||
strictEqual(result, 'ABC');
|
||||
});
|
||||
|
||||
it('writeln', async () => {
|
||||
await writelnSync('foo');
|
||||
await writelnSync('bar');
|
||||
await writelnSync('文');
|
||||
lineEquals(0, 'foo');
|
||||
lineEquals(1, 'bar');
|
||||
lineEquals(2, '文');
|
||||
});
|
||||
|
||||
it('writeln with callback', async () => {
|
||||
let result: string | undefined;
|
||||
await new Promise<void>(r => {
|
||||
term.writeln('foo', () => { result = '1'; });
|
||||
term.writeln('bar', () => { result += '2'; });
|
||||
term.writeln('文', () => {
|
||||
result += '3';
|
||||
r();
|
||||
});
|
||||
});
|
||||
lineEquals(0, 'foo');
|
||||
lineEquals(1, 'bar');
|
||||
lineEquals(2, '文');
|
||||
strictEqual(result, '123');
|
||||
});
|
||||
|
||||
it('writeln - bytes (UTF8)', async () => {
|
||||
await writelnSync(new Uint8Array([102, 111, 111]));
|
||||
await writelnSync(new Uint8Array([98, 97, 114]));
|
||||
await writelnSync(new Uint8Array([230, 150, 135]));
|
||||
lineEquals(0, 'foo');
|
||||
lineEquals(1, 'bar');
|
||||
lineEquals(2, '文');
|
||||
});
|
||||
|
||||
it('clear', async () => {
|
||||
term = new Terminal({ rows: 5 });
|
||||
for (let i = 0; i < 10; i++) {
|
||||
await writeSync('\n\rtest' + i);
|
||||
}
|
||||
term.clear();
|
||||
strictEqual(term.buffer.active.length, 5);
|
||||
lineEquals(0, 'test9');
|
||||
for (let i = 1; i < 5; i++) {
|
||||
lineEquals(i, '');
|
||||
}
|
||||
});
|
||||
|
||||
it('getOption, setOption', async () => {
|
||||
strictEqual(term.getOption('scrollback'), 1000);
|
||||
term.setOption('scrollback', 50);
|
||||
strictEqual(term.getOption('scrollback'), 50);
|
||||
});
|
||||
|
||||
describe('loadAddon', () => {
|
||||
it('constructor', async () => {
|
||||
term = new Terminal({ cols: 5 });
|
||||
let cols = 0;
|
||||
term.loadAddon({
|
||||
activate: (t) => cols = t.cols,
|
||||
dispose: () => {}
|
||||
});
|
||||
strictEqual(cols, 5);
|
||||
});
|
||||
|
||||
it('dispose (addon)', async () => {
|
||||
let disposeCalled = false;
|
||||
const addon = {
|
||||
activate: () => {},
|
||||
dispose: () => disposeCalled = true
|
||||
};
|
||||
term.loadAddon(addon);
|
||||
strictEqual(disposeCalled, false);
|
||||
addon.dispose();
|
||||
strictEqual(disposeCalled, true);
|
||||
});
|
||||
|
||||
it('dispose (terminal)', async () => {
|
||||
let disposeCalled = false;
|
||||
term.loadAddon({
|
||||
activate: () => {},
|
||||
dispose: () => disposeCalled = true
|
||||
});
|
||||
strictEqual(disposeCalled, false);
|
||||
term.dispose();
|
||||
strictEqual(disposeCalled, true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Events', () => {
|
||||
it('onCursorMove', async () => {
|
||||
let callCount = 0;
|
||||
term.onCursorMove(e => callCount++);
|
||||
await writeSync('foo');
|
||||
strictEqual(callCount, 1);
|
||||
await writeSync('bar');
|
||||
strictEqual(callCount, 2);
|
||||
});
|
||||
|
||||
it('onData', async () => {
|
||||
const calls: string[] = [];
|
||||
term.onData(e => calls.push(e));
|
||||
await writeSync('\x1b[5n'); // DSR Status Report
|
||||
deepStrictEqual(calls, ['\x1b[0n']);
|
||||
});
|
||||
|
||||
it('onLineFeed', async () => {
|
||||
let callCount = 0;
|
||||
term.onLineFeed(() => callCount++);
|
||||
await writelnSync('foo');
|
||||
strictEqual(callCount, 1);
|
||||
await writelnSync('bar');
|
||||
strictEqual(callCount, 2);
|
||||
});
|
||||
|
||||
it('onScroll', async () => {
|
||||
term = new Terminal({ rows: 5 });
|
||||
const calls: number[] = [];
|
||||
term.onScroll(e => calls.push(e));
|
||||
for (let i = 0; i < 4; i++) {
|
||||
await writelnSync('foo');
|
||||
}
|
||||
deepStrictEqual(calls, []);
|
||||
await writelnSync('bar');
|
||||
deepStrictEqual(calls, [1]);
|
||||
await writelnSync('baz');
|
||||
deepStrictEqual(calls, [1, 2]);
|
||||
});
|
||||
|
||||
it('onResize', async () => {
|
||||
const calls: [number, number][] = [];
|
||||
term.onResize(e => calls.push([e.cols, e.rows]));
|
||||
deepStrictEqual(calls, []);
|
||||
term.resize(10, 5);
|
||||
deepStrictEqual(calls, [[10, 5]]);
|
||||
term.resize(20, 15);
|
||||
deepStrictEqual(calls, [[10, 5], [20, 15]]);
|
||||
});
|
||||
|
||||
it('onTitleChange', async () => {
|
||||
const calls: string[] = [];
|
||||
term.onTitleChange(e => calls.push(e));
|
||||
deepStrictEqual(calls, []);
|
||||
await writeSync('\x1b]2;foo\x9c');
|
||||
deepStrictEqual(calls, ['foo']);
|
||||
});
|
||||
|
||||
it('onBell', async () => {
|
||||
const calls: boolean[] = [];
|
||||
term.onBell(() => calls.push(true));
|
||||
deepStrictEqual(calls, []);
|
||||
await writeSync('\x07');
|
||||
deepStrictEqual(calls, [true]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('buffer', () => {
|
||||
it('cursorX, cursorY', async () => {
|
||||
term = new Terminal({ rows: 5, cols: 5 });
|
||||
strictEqual(term.buffer.active.cursorX, 0);
|
||||
strictEqual(term.buffer.active.cursorY, 0);
|
||||
await writeSync('foo');
|
||||
strictEqual(term.buffer.active.cursorX, 3);
|
||||
strictEqual(term.buffer.active.cursorY, 0);
|
||||
await writeSync('\n');
|
||||
strictEqual(term.buffer.active.cursorX, 3);
|
||||
strictEqual(term.buffer.active.cursorY, 1);
|
||||
await writeSync('\r');
|
||||
strictEqual(term.buffer.active.cursorX, 0);
|
||||
strictEqual(term.buffer.active.cursorY, 1);
|
||||
await writeSync('abcde');
|
||||
strictEqual(term.buffer.active.cursorX, 5);
|
||||
strictEqual(term.buffer.active.cursorY, 1);
|
||||
await writeSync('\n\r\n\n\n\n\n');
|
||||
strictEqual(term.buffer.active.cursorX, 0);
|
||||
strictEqual(term.buffer.active.cursorY, 4);
|
||||
});
|
||||
|
||||
it('viewportY', async () => {
|
||||
term = new Terminal({ rows: 5 });
|
||||
strictEqual(term.buffer.active.viewportY, 0);
|
||||
await writeSync('\n\n\n\n');
|
||||
strictEqual(term.buffer.active.viewportY, 0);
|
||||
await writeSync('\n');
|
||||
strictEqual(term.buffer.active.viewportY, 1);
|
||||
await writeSync('\n\n\n\n');
|
||||
strictEqual(term.buffer.active.viewportY, 5);
|
||||
term.scrollLines(-1);
|
||||
strictEqual(term.buffer.active.viewportY, 4);
|
||||
term.scrollToTop();
|
||||
strictEqual(term.buffer.active.viewportY, 0);
|
||||
});
|
||||
|
||||
it('baseY', async () => {
|
||||
term = new Terminal({ rows: 5 });
|
||||
strictEqual(term.buffer.active.baseY, 0);
|
||||
await writeSync('\n\n\n\n');
|
||||
strictEqual(term.buffer.active.baseY, 0);
|
||||
await writeSync('\n');
|
||||
strictEqual(term.buffer.active.baseY, 1);
|
||||
await writeSync('\n\n\n\n');
|
||||
strictEqual(term.buffer.active.baseY, 5);
|
||||
term.scrollLines(-1);
|
||||
strictEqual(term.buffer.active.baseY, 5);
|
||||
term.scrollToTop();
|
||||
strictEqual(term.buffer.active.baseY, 5);
|
||||
});
|
||||
|
||||
it('length', async () => {
|
||||
term = new Terminal({ rows: 5 });
|
||||
strictEqual(term.buffer.active.length, 5);
|
||||
await writeSync('\n\n\n\n');
|
||||
strictEqual(term.buffer.active.length, 5);
|
||||
await writeSync('\n');
|
||||
strictEqual(term.buffer.active.length, 6);
|
||||
await writeSync('\n\n\n\n');
|
||||
strictEqual(term.buffer.active.length, 10);
|
||||
});
|
||||
|
||||
describe('getLine', () => {
|
||||
it('invalid index', async () => {
|
||||
term = new Terminal({ rows: 5 });
|
||||
strictEqual(term.buffer.active.getLine(-1), undefined);
|
||||
strictEqual(term.buffer.active.getLine(5), undefined);
|
||||
});
|
||||
|
||||
it('isWrapped', async () => {
|
||||
term = new Terminal({ cols: 5 });
|
||||
strictEqual(term.buffer.active.getLine(0)!.isWrapped, false);
|
||||
strictEqual(term.buffer.active.getLine(1)!.isWrapped, false);
|
||||
await writeSync('abcde');
|
||||
strictEqual(term.buffer.active.getLine(0)!.isWrapped, false);
|
||||
strictEqual(term.buffer.active.getLine(1)!.isWrapped, false);
|
||||
await writeSync('f');
|
||||
strictEqual(term.buffer.active.getLine(0)!.isWrapped, false);
|
||||
strictEqual(term.buffer.active.getLine(1)!.isWrapped, true);
|
||||
});
|
||||
|
||||
it('translateToString', async () => {
|
||||
term = new Terminal({ cols: 5 });
|
||||
strictEqual(term.buffer.active.getLine(0)!.translateToString(), ' ');
|
||||
strictEqual(term.buffer.active.getLine(0)!.translateToString(true), '');
|
||||
await writeSync('foo');
|
||||
strictEqual(term.buffer.active.getLine(0)!.translateToString(), 'foo ');
|
||||
strictEqual(term.buffer.active.getLine(0)!.translateToString(true), 'foo');
|
||||
await writeSync('bar');
|
||||
strictEqual(term.buffer.active.getLine(0)!.translateToString(), 'fooba');
|
||||
strictEqual(term.buffer.active.getLine(0)!.translateToString(true), 'fooba');
|
||||
strictEqual(term.buffer.active.getLine(1)!.translateToString(true), 'r');
|
||||
strictEqual(term.buffer.active.getLine(0)!.translateToString(false, 1), 'ooba');
|
||||
strictEqual(term.buffer.active.getLine(0)!.translateToString(false, 1, 3), 'oo');
|
||||
});
|
||||
|
||||
it('getCell', async () => {
|
||||
term = new Terminal({ cols: 5 });
|
||||
strictEqual(term.buffer.active.getLine(0)!.getCell(-1), undefined);
|
||||
strictEqual(term.buffer.active.getLine(0)!.getCell(5), undefined);
|
||||
strictEqual(term.buffer.active.getLine(0)!.getCell(0)!.getChars(), '');
|
||||
strictEqual(term.buffer.active.getLine(0)!.getCell(0)!.getWidth(), 1);
|
||||
await writeSync('a文');
|
||||
strictEqual(term.buffer.active.getLine(0)!.getCell(0)!.getChars(), 'a');
|
||||
strictEqual(term.buffer.active.getLine(0)!.getCell(0)!.getWidth(), 1);
|
||||
strictEqual(term.buffer.active.getLine(0)!.getCell(1)!.getChars(), '文');
|
||||
strictEqual(term.buffer.active.getLine(0)!.getCell(1)!.getWidth(), 2);
|
||||
strictEqual(term.buffer.active.getLine(0)!.getCell(2)!.getChars(), '');
|
||||
strictEqual(term.buffer.active.getLine(0)!.getCell(2)!.getWidth(), 0);
|
||||
});
|
||||
});
|
||||
|
||||
it('active, normal, alternate', async () => {
|
||||
term = new Terminal({ cols: 5 });
|
||||
strictEqual(term.buffer.active.type, 'normal');
|
||||
strictEqual(term.buffer.normal.type, 'normal');
|
||||
strictEqual(term.buffer.alternate.type, 'alternate');
|
||||
|
||||
await writeSync('norm ');
|
||||
strictEqual(term.buffer.active.getLine(0)!.translateToString(), 'norm ');
|
||||
strictEqual(term.buffer.normal.getLine(0)!.translateToString(), 'norm ');
|
||||
strictEqual(term.buffer.alternate.getLine(0), undefined);
|
||||
|
||||
await writeSync('\x1b[?47h\r'); // use alternate screen buffer
|
||||
strictEqual(term.buffer.active.type, 'alternate');
|
||||
strictEqual(term.buffer.normal.type, 'normal');
|
||||
strictEqual(term.buffer.alternate.type, 'alternate');
|
||||
|
||||
strictEqual(term.buffer.active.getLine(0)!.translateToString(), ' ');
|
||||
await writeSync('alt ');
|
||||
strictEqual(term.buffer.active.getLine(0)!.translateToString(), 'alt ');
|
||||
strictEqual(term.buffer.normal.getLine(0)!.translateToString(), 'norm ');
|
||||
strictEqual(term.buffer.alternate.getLine(0)!.translateToString(), 'alt ');
|
||||
|
||||
await writeSync('\x1b[?47l\r'); // use normal screen buffer
|
||||
strictEqual(term.buffer.active.type, 'normal');
|
||||
strictEqual(term.buffer.normal.type, 'normal');
|
||||
strictEqual(term.buffer.alternate.type, 'alternate');
|
||||
|
||||
strictEqual(term.buffer.active.getLine(0)!.translateToString(), 'norm ');
|
||||
strictEqual(term.buffer.normal.getLine(0)!.translateToString(), 'norm ');
|
||||
strictEqual(term.buffer.alternate.getLine(0), undefined);
|
||||
});
|
||||
});
|
||||
|
||||
it('dispose', async () => {
|
||||
term.dispose();
|
||||
strictEqual((term as any)._core._isDisposed, true);
|
||||
});
|
||||
});
|
||||
|
||||
function writeSync(text: string | Uint8Array): Promise<void> {
|
||||
return new Promise<void>(r => term.write(text, r));
|
||||
}
|
||||
|
||||
function writelnSync(text: string | Uint8Array): Promise<void> {
|
||||
return new Promise<void>(r => term.writeln(text, r));
|
||||
}
|
||||
|
||||
function lineEquals(index: number, text: string): void {
|
||||
strictEqual(term.buffer.active.getLine(index)!.translateToString(true), text);
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
* Copyright (c) 2018 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { IEvent } from 'common/EventEmitter';
|
||||
import { BufferNamespaceApi } from 'common/public/BufferNamespaceApi';
|
||||
import { ParserApi } from 'common/public/ParserApi';
|
||||
import { UnicodeApi } from 'common/public/UnicodeApi';
|
||||
import { IBufferNamespace as IBufferNamespaceApi, IMarker, IParser, ITerminalAddon, ITerminalOptions, IUnicodeHandling, Terminal as ITerminalApi } from 'xterm-headless';
|
||||
import { Terminal as TerminalCore } from 'headless/Terminal';
|
||||
import { AddonManager } from 'common/public/AddonManager';
|
||||
|
||||
export class Terminal implements ITerminalApi {
|
||||
private _core: TerminalCore;
|
||||
private _addonManager: AddonManager;
|
||||
private _parser: IParser | undefined;
|
||||
private _buffer: BufferNamespaceApi | undefined;
|
||||
|
||||
constructor(options?: ITerminalOptions) {
|
||||
this._core = new TerminalCore(options);
|
||||
this._addonManager = new AddonManager();
|
||||
}
|
||||
|
||||
private _checkProposedApi(): void {
|
||||
if (!this._core.optionsService.options.allowProposedApi) {
|
||||
throw new Error('You must set the allowProposedApi option to true to use proposed API');
|
||||
}
|
||||
}
|
||||
|
||||
public get onBell(): IEvent<void> { return this._core.onBell; }
|
||||
public get onBinary(): IEvent<string> { return this._core.onBinary; }
|
||||
public get onCursorMove(): IEvent<void> { return this._core.onCursorMove; }
|
||||
public get onData(): IEvent<string> { return this._core.onData; }
|
||||
public get onLineFeed(): IEvent<void> { return this._core.onLineFeed; }
|
||||
public get onResize(): IEvent<{ cols: number, rows: number }> { return this._core.onResize; }
|
||||
public get onScroll(): IEvent<number> { return this._core.onScroll; }
|
||||
public get onTitleChange(): IEvent<string> { return this._core.onTitleChange; }
|
||||
|
||||
public get parser(): IParser {
|
||||
this._checkProposedApi();
|
||||
if (!this._parser) {
|
||||
this._parser = new ParserApi(this._core);
|
||||
}
|
||||
return this._parser;
|
||||
}
|
||||
public get unicode(): IUnicodeHandling {
|
||||
this._checkProposedApi();
|
||||
return new UnicodeApi(this._core);
|
||||
}
|
||||
public get rows(): number { return this._core.rows; }
|
||||
public get cols(): number { return this._core.cols; }
|
||||
public get buffer(): IBufferNamespaceApi {
|
||||
this._checkProposedApi();
|
||||
if (!this._buffer) {
|
||||
this._buffer = new BufferNamespaceApi(this._core);
|
||||
}
|
||||
return this._buffer;
|
||||
}
|
||||
public get markers(): ReadonlyArray<IMarker> {
|
||||
this._checkProposedApi();
|
||||
return this._core.markers;
|
||||
}
|
||||
public resize(columns: number, rows: number): void {
|
||||
this._verifyIntegers(columns, rows);
|
||||
this._core.resize(columns, rows);
|
||||
}
|
||||
public registerMarker(cursorYOffset: number): IMarker | undefined {
|
||||
this._checkProposedApi();
|
||||
this._verifyIntegers(cursorYOffset);
|
||||
return this._core.addMarker(cursorYOffset);
|
||||
}
|
||||
public addMarker(cursorYOffset: number): IMarker | undefined {
|
||||
return this.registerMarker(cursorYOffset);
|
||||
}
|
||||
public dispose(): void {
|
||||
this._addonManager.dispose();
|
||||
this._core.dispose();
|
||||
}
|
||||
public scrollLines(amount: number): void {
|
||||
this._verifyIntegers(amount);
|
||||
this._core.scrollLines(amount);
|
||||
}
|
||||
public scrollPages(pageCount: number): void {
|
||||
this._verifyIntegers(pageCount);
|
||||
this._core.scrollPages(pageCount);
|
||||
}
|
||||
public scrollToTop(): void {
|
||||
this._core.scrollToTop();
|
||||
}
|
||||
public scrollToBottom(): void {
|
||||
this._core.scrollToBottom();
|
||||
}
|
||||
public scrollToLine(line: number): void {
|
||||
this._verifyIntegers(line);
|
||||
this._core.scrollToLine(line);
|
||||
}
|
||||
public clear(): void {
|
||||
this._core.clear();
|
||||
}
|
||||
public write(data: string | Uint8Array, callback?: () => void): void {
|
||||
this._core.write(data, callback);
|
||||
}
|
||||
public writeUtf8(data: Uint8Array, callback?: () => void): void {
|
||||
this._core.write(data, callback);
|
||||
}
|
||||
public writeln(data: string | Uint8Array, callback?: () => void): void {
|
||||
this._core.write(data);
|
||||
this._core.write('\r\n', callback);
|
||||
}
|
||||
public getOption(key: 'bellSound' | 'bellStyle' | 'cursorStyle' | 'fontFamily' | 'logLevel' | 'rendererType' | 'termName' | 'wordSeparator'): string;
|
||||
public getOption(key: 'allowTransparency' | 'altClickMovesCursor' | 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'disableStdin' | 'macOptionIsMeta' | 'rightClickSelectsWord' | 'popOnBell' | 'visualBell'): boolean;
|
||||
public getOption(key: 'cols' | 'fontSize' | 'letterSpacing' | 'lineHeight' | 'rows' | 'tabStopWidth' | 'scrollback'): number;
|
||||
public getOption(key: string): any;
|
||||
public getOption(key: any): any {
|
||||
return this._core.optionsService.getOption(key);
|
||||
}
|
||||
public setOption(key: 'bellSound' | 'fontFamily' | 'termName' | 'wordSeparator', value: string): void;
|
||||
public setOption(key: 'fontWeight' | 'fontWeightBold', value: 'normal' | 'bold' | '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900' | number): void;
|
||||
public setOption(key: 'logLevel', value: 'debug' | 'info' | 'warn' | 'error' | 'off'): void;
|
||||
public setOption(key: 'bellStyle', value: 'none' | 'visual' | 'sound' | 'both'): void;
|
||||
public setOption(key: 'cursorStyle', value: 'block' | 'underline' | 'bar'): void;
|
||||
public setOption(key: 'allowTransparency' | 'altClickMovesCursor' | 'cancelEvents' | 'convertEol' | 'cursorBlink' | 'disableStdin' | 'macOptionIsMeta' | 'rightClickSelectsWord' | 'popOnBell' | 'visualBell', value: boolean): void;
|
||||
public setOption(key: 'fontSize' | 'letterSpacing' | 'lineHeight' | 'tabStopWidth' | 'scrollback', value: number): void;
|
||||
public setOption(key: 'cols' | 'rows', value: number): void;
|
||||
public setOption(key: string, value: any): void;
|
||||
public setOption(key: any, value: any): void {
|
||||
this._core.optionsService.setOption(key, value);
|
||||
}
|
||||
public reset(): void {
|
||||
this._core.reset();
|
||||
}
|
||||
public loadAddon(addon: ITerminalAddon): void {
|
||||
// TODO: This could cause issues if the addon calls renderer apis
|
||||
return this._addonManager.loadAddon(this as any, addon);
|
||||
}
|
||||
|
||||
private _verifyIntegers(...values: number[]): void {
|
||||
for (const value of values) {
|
||||
if (value === Infinity || isNaN(value) || value % 1 !== 0) {
|
||||
throw new Error('This API only accepts integers');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"extends": "../tsconfig-library-base",
|
||||
"compilerOptions": {
|
||||
"lib": [
|
||||
"es2015",
|
||||
"es2016.Array.Include"
|
||||
],
|
||||
"outDir": "../../out",
|
||||
"types": [
|
||||
"../../node_modules/@types/mocha",
|
||||
"../../node_modules/@types/node"
|
||||
],
|
||||
"baseUrl": "../",
|
||||
"paths": {
|
||||
"common/*": [ "./common/*" ]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"./**/*",
|
||||
"../../typings/xterm.d.ts", // common/Types.d.ts imports from 'xterm'
|
||||
"../../typings/xterm-headless.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "../common" }
|
||||
]
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user