Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add options to headless typings #3599

Merged
merged 3 commits into from
Jan 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 35 additions & 4 deletions src/headless/public/Terminal.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@

import { deepStrictEqual, strictEqual, throws } from 'assert';
import { Terminal } from 'headless/public/Terminal';
import { ITerminalOptions } from 'xterm-headless';

let term: Terminal;

describe('Headless API Tests', function(): void {
describe('Headless API Tests', function (): void {
beforeEach(() => {
// Create default terminal to be used by most tests
term = new Terminal();
Expand Down Expand Up @@ -119,21 +120,51 @@ describe('Headless API Tests', function(): void {
strictEqual(term.getOption('scrollback'), 50);
});

describe('options', () => {
const termOptions = {
cols: 80,
rows: 24
};

beforeEach(async () => {
term = new Terminal(termOptions);
});
it('get options', () => {
const options: ITerminalOptions = term.options;
strictEqual(options.cols, 80);
strictEqual(options.rows, 24);
});
it('set options', async () => {
const options: ITerminalOptions = term.options;
throws(() => options.cols = 40);
throws(() => options.rows = 20);
term.options.scrollback = 1;
strictEqual(term.options.scrollback, 1);
term.options= {
fontSize: 12,
fontFamily: 'Arial'
};
strictEqual(term.options.fontSize, 12);
strictEqual(term.options.fontFamily, 'Arial');
});
});


describe('loadAddon', () => {
it('constructor', async () => {
term = new Terminal({ cols: 5 });
let cols = 0;
term.loadAddon({
activate: (t) => cols = t.cols,
dispose: () => {}
dispose: () => { }
});
strictEqual(cols, 5);
});

it('dispose (addon)', async () => {
let disposeCalled = false;
const addon = {
activate: () => {},
activate: () => { },
dispose: () => disposeCalled = true
};
term.loadAddon(addon);
Expand All @@ -145,7 +176,7 @@ describe('Headless API Tests', function(): void {
it('dispose (terminal)', async () => {
let disposeCalled = false;
term.loadAddon({
activate: () => {},
activate: () => { },
dispose: () => disposeCalled = true
});
strictEqual(disposeCalled, false);
Expand Down
52 changes: 51 additions & 1 deletion src/headless/public/Terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,61 @@ 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, IModes, IParser, ITerminalAddon, ITerminalOptions, IUnicodeHandling, Terminal as ITerminalApi } from 'xterm-headless';
import { IBufferNamespace as IBufferNamespaceApi, IMarker, IModes, IParser, ITerminalAddon, IUnicodeHandling, Terminal as ITerminalApi } from 'xterm-headless';
import { Terminal as TerminalCore } from 'headless/Terminal';
import { AddonManager } from 'common/public/AddonManager';
import { ITerminalOptions } from 'common/Types';

/**
* The set of options that only have an effect when set in the Terminal constructor.
*/
const CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows'];

export class Terminal implements ITerminalApi {
private _core: TerminalCore;
private _addonManager: AddonManager;
private _parser: IParser | undefined;
private _buffer: BufferNamespaceApi | undefined;
private _publicOptions: ITerminalOptions;

constructor(options?: ITerminalOptions) {
this._core = new TerminalCore(options);
this._addonManager = new AddonManager();

this._publicOptions = { ... this._core.options };
const getter = (propName: string): any => {
return this._core.options[propName];
};
const setter = (propName: string, value: any): void => {
this._checkReadonlyOptions(propName);
this._core.options[propName] = value;
};

for (const propName in this._core.options) {
Object.defineProperty(this._publicOptions, propName, {
get: () => {
return this._core.options[propName];
},
set: (value: any) => {
this._checkReadonlyOptions(propName);
this._core.options[propName] = value;
}
});
const desc = {
get: getter.bind(this, propName),
set: setter.bind(this, propName)
};
Object.defineProperty(this._publicOptions, propName, desc);
}
}

private _checkReadonlyOptions(propName: string): void {
// Throw an error if any constructor only option is modified
// from terminal.options
// Modifications from anywhere else are allowed
if (CONSTRUCTOR_ONLY_OPTIONS.includes(propName)) {
throw new Error(`Option "${propName}" can only be set in the constructor`);
}
}

private _checkProposedApi(): void {
Expand Down Expand Up @@ -82,6 +124,14 @@ export class Terminal implements ITerminalApi {
wraparoundMode: m.wraparound
};
}
public get options(): ITerminalOptions {
return this._publicOptions;
}
public set options(options: ITerminalOptions) {
for (const propName in options) {
this._publicOptions[propName] = options[propName];
}
}
public resize(columns: number, rows: number): void {
this._verifyIntegers(columns, rows);
this._core.resize(columns, rows);
Expand Down
23 changes: 23 additions & 0 deletions typings/xterm-headless.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,29 @@ declare module 'xterm-headless' {
*/
readonly modes: IModes;

/**
* Gets or sets the terminal options. This supports setting multiple options.
*
* @example Get a single option
* ```typescript
* console.log(terminal.options.fontSize);
* ```
*
* @example Set a single option
* ```typescript
* terminal.options.fontSize = 12;
* ```
*
* @example Set multiple options
* ```typescript
* terminal.options = {
* fontSize: 12,
* fontFamily: 'Arial',
* };
* ```
*/
options: ITerminalOptions;

/**
* Natural language strings that can be localized.
*/
Expand Down