Merge branch 'master' into utf8_input
This commit is contained in:
@@ -16,7 +16,7 @@ class TestTerminal extends Terminal {
|
||||
public keyPress(ev: any): boolean { return this._keyPress(ev); }
|
||||
}
|
||||
|
||||
describe('xterm.js', () => {
|
||||
describe('Terminal', () => {
|
||||
let term: TestTerminal;
|
||||
const termOptions = {
|
||||
cols: INIT_COLS,
|
||||
|
||||
+49
-48
@@ -221,55 +221,56 @@ export interface ITerminal extends IPublicTerminal, IElementAccessor, IBufferAcc
|
||||
showCursor(): void;
|
||||
}
|
||||
|
||||
// Portions of the public API that are required by the internal Terminal
|
||||
export interface IPublicTerminal extends IDisposable, IEventEmitter {
|
||||
textarea: HTMLTextAreaElement;
|
||||
rows: number;
|
||||
cols: number;
|
||||
buffer: IBuffer;
|
||||
markers: IMarker[];
|
||||
onCursorMove: IEvent<void>;
|
||||
onData: IEvent<string>;
|
||||
onKey: IEvent<{ key: string, domEvent: KeyboardEvent }>;
|
||||
onLineFeed: IEvent<void>;
|
||||
onScroll: IEvent<number>;
|
||||
onSelectionChange: IEvent<void>;
|
||||
onRender: IEvent<{ start: number, end: number }>;
|
||||
onResize: IEvent<{ cols: number, rows: number }>;
|
||||
onTitleChange: IEvent<string>;
|
||||
blur(): void;
|
||||
focus(): void;
|
||||
resize(columns: number, rows: number): void;
|
||||
writeln(data: string): void;
|
||||
open(parent: HTMLElement): void;
|
||||
attachCustomKeyEventHandler(customKeyEventHandler: (event: KeyboardEvent) => boolean): void;
|
||||
addCsiHandler(flag: string, callback: (params: number[], collect: string) => boolean): IDisposable;
|
||||
addOscHandler(ident: number, callback: (data: string) => boolean): IDisposable;
|
||||
registerLinkMatcher(regex: RegExp, handler: (event: MouseEvent, uri: string) => void, options?: ILinkMatcherOptions): number;
|
||||
deregisterLinkMatcher(matcherId: number): void;
|
||||
registerCharacterJoiner(handler: (text: string) => [number, number][]): number;
|
||||
deregisterCharacterJoiner(joinerId: number): void;
|
||||
addMarker(cursorYOffset: number): IMarker;
|
||||
hasSelection(): boolean;
|
||||
getSelection(): string;
|
||||
getSelectionPosition(): ISelectionPosition | undefined;
|
||||
clearSelection(): void;
|
||||
select(column: number, row: number, length: number): void;
|
||||
selectAll(): void;
|
||||
selectLines(start: number, end: number): void;
|
||||
dispose(): void;
|
||||
destroy(): void;
|
||||
scrollLines(amount: number): void;
|
||||
scrollPages(pageCount: number): void;
|
||||
scrollToTop(): void;
|
||||
scrollToBottom(): void;
|
||||
scrollToLine(line: number): void;
|
||||
clear(): void;
|
||||
write(data: string): void;
|
||||
writeUtf8(data: Uint8Array): void;
|
||||
getOption(key: string): any;
|
||||
setOption(key: string, value: any): void;
|
||||
refresh(start: number, end: number): void;
|
||||
reset(): void;
|
||||
textarea: HTMLTextAreaElement;
|
||||
rows: number;
|
||||
cols: number;
|
||||
buffer: IBuffer;
|
||||
markers: IMarker[];
|
||||
onCursorMove: IEvent<void>;
|
||||
onData: IEvent<string>;
|
||||
onKey: IEvent<{ key: string, domEvent: KeyboardEvent }>;
|
||||
onLineFeed: IEvent<void>;
|
||||
onScroll: IEvent<number>;
|
||||
onSelectionChange: IEvent<void>;
|
||||
onRender: IEvent<{ start: number, end: number }>;
|
||||
onResize: IEvent<{ cols: number, rows: number }>;
|
||||
onTitleChange: IEvent<string>;
|
||||
blur(): void;
|
||||
focus(): void;
|
||||
resize(columns: number, rows: number): void;
|
||||
writeln(data: string): void;
|
||||
open(parent: HTMLElement): void;
|
||||
attachCustomKeyEventHandler(customKeyEventHandler: (event: KeyboardEvent) => boolean): void;
|
||||
addCsiHandler(flag: string, callback: (params: number[], collect: string) => boolean): IDisposable;
|
||||
addOscHandler(ident: number, callback: (data: string) => boolean): IDisposable;
|
||||
registerLinkMatcher(regex: RegExp, handler: (event: MouseEvent, uri: string) => void, options?: ILinkMatcherOptions): number;
|
||||
deregisterLinkMatcher(matcherId: number): void;
|
||||
registerCharacterJoiner(handler: (text: string) => [number, number][]): number;
|
||||
deregisterCharacterJoiner(joinerId: number): void;
|
||||
addMarker(cursorYOffset: number): IMarker;
|
||||
hasSelection(): boolean;
|
||||
getSelection(): string;
|
||||
getSelectionPosition(): ISelectionPosition | undefined;
|
||||
clearSelection(): void;
|
||||
select(column: number, row: number, length: number): void;
|
||||
selectAll(): void;
|
||||
selectLines(start: number, end: number): void;
|
||||
dispose(): void;
|
||||
destroy(): void;
|
||||
scrollLines(amount: number): void;
|
||||
scrollPages(pageCount: number): void;
|
||||
scrollToTop(): void;
|
||||
scrollToBottom(): void;
|
||||
scrollToLine(line: number): void;
|
||||
clear(): void;
|
||||
write(data: string): void;
|
||||
writeUtf8(data: Uint8Array): void;
|
||||
getOption(key: string): any;
|
||||
setOption(key: string, value: any): void;
|
||||
refresh(start: number, end: number): void;
|
||||
reset(): void;
|
||||
}
|
||||
|
||||
export interface IBufferAccessor {
|
||||
|
||||
@@ -5,14 +5,8 @@
|
||||
|
||||
import { Terminal } from 'xterm';
|
||||
|
||||
// TODO: Don't rely on this private API
|
||||
export interface ITerminalCore {
|
||||
buffer: any;
|
||||
}
|
||||
|
||||
export interface ISearchAddonTerminal extends Terminal {
|
||||
__searchHelper?: ISearchHelper;
|
||||
_core: ITerminalCore;
|
||||
}
|
||||
|
||||
export interface ISearchHelper {
|
||||
|
||||
@@ -44,7 +44,7 @@ export class SearchHelper implements ISearchHelper {
|
||||
}
|
||||
|
||||
let startCol: number = 0;
|
||||
let startRow = this._terminal._core.buffer.ydisp;
|
||||
let startRow = this._terminal.buffer.viewportY;
|
||||
|
||||
if (this._terminal.hasSelection()) {
|
||||
// Start from the selection end if there is a selection
|
||||
@@ -62,7 +62,7 @@ export class SearchHelper implements ISearchHelper {
|
||||
let cumulativeCols = startCol;
|
||||
// If startRow is wrapped row, scan for unwrapped row above.
|
||||
// So we can start matching on wrapped line from long unwrapped line.
|
||||
while (this._terminal._core.buffer.lines.get(findingRow).isWrapped) {
|
||||
while (this._terminal.buffer.getLine(findingRow).isWrapped) {
|
||||
findingRow--;
|
||||
cumulativeCols += this._terminal.cols;
|
||||
}
|
||||
@@ -73,7 +73,7 @@ export class SearchHelper implements ISearchHelper {
|
||||
// Search from startRow + 1 to end
|
||||
if (!result) {
|
||||
|
||||
for (let y = startRow + 1; y < this._terminal._core.buffer.ybase + this._terminal.rows; y++) {
|
||||
for (let y = startRow + 1; y < this._terminal.buffer.baseY + this._terminal.rows; y++) {
|
||||
|
||||
// If the current line is wrapped line, increase index of column to ignore the previous scan
|
||||
// Otherwise, reset beginning column index to zero with set new unwrapped line index
|
||||
@@ -115,7 +115,7 @@ export class SearchHelper implements ISearchHelper {
|
||||
}
|
||||
|
||||
const isReverseSearch = true;
|
||||
let startRow = this._terminal._core.buffer.ydisp + this._terminal.rows - 1;
|
||||
let startRow = this._terminal.buffer.viewportY + this._terminal.rows - 1;
|
||||
let startCol = this._terminal.cols;
|
||||
|
||||
if (this._terminal.hasSelection()) {
|
||||
@@ -135,7 +135,7 @@ export class SearchHelper implements ISearchHelper {
|
||||
// If the line is wrapped line, increase number of columns that is needed to be scanned
|
||||
// Se we can scan on wrapped line from unwrapped line
|
||||
let cumulativeCols = this._terminal.cols;
|
||||
if (this._terminal._core.buffer.lines.get(startRow).isWrapped) {
|
||||
if (this._terminal.buffer.getLine(startRow).isWrapped) {
|
||||
cumulativeCols += startCol;
|
||||
}
|
||||
for (let y = startRow - 1; y >= 0; y--) {
|
||||
@@ -145,7 +145,7 @@ export class SearchHelper implements ISearchHelper {
|
||||
}
|
||||
// If the current line is wrapped line, increase scanning range,
|
||||
// preparing for scanning on unwrapped line
|
||||
if (this._terminal._core.buffer.lines.get(y).isWrapped) {
|
||||
if (this._terminal.buffer.getLine(y).isWrapped) {
|
||||
cumulativeCols += this._terminal.cols;
|
||||
} else {
|
||||
cumulativeCols = this._terminal.cols;
|
||||
@@ -156,14 +156,14 @@ export class SearchHelper implements ISearchHelper {
|
||||
// Search from the bottom to startRow (search the whole startRow again in
|
||||
// case startCol > 0)
|
||||
if (!result) {
|
||||
const searchFrom = this._terminal._core.buffer.ybase + this._terminal.rows - 1;
|
||||
const searchFrom = this._terminal.buffer.baseY + this._terminal.rows - 1;
|
||||
let cumulativeCols = this._terminal.cols;
|
||||
for (let y = searchFrom; y >= startRow; y--) {
|
||||
result = this._findInLine(term, y, cumulativeCols, searchOptions, isReverseSearch);
|
||||
if (result) {
|
||||
break;
|
||||
}
|
||||
if (this._terminal._core.buffer.lines.get(y).isWrapped) {
|
||||
if (this._terminal.buffer.getLine(y).isWrapped) {
|
||||
cumulativeCols += this._terminal.cols;
|
||||
} else {
|
||||
cumulativeCols = this._terminal.cols;
|
||||
@@ -180,7 +180,7 @@ export class SearchHelper implements ISearchHelper {
|
||||
*/
|
||||
private _initLinesCache(): void {
|
||||
if (!this._linesCache) {
|
||||
this._linesCache = new Array(this._terminal._core.buffer.length);
|
||||
this._linesCache = new Array(this._terminal.buffer.length);
|
||||
this._cursorMoveListener = this._terminal.onCursorMove(() => this._destroyLinesCache());
|
||||
this._resizeListener = this._terminal.onResize(() => this._destroyLinesCache());
|
||||
}
|
||||
@@ -230,7 +230,7 @@ export class SearchHelper implements ISearchHelper {
|
||||
protected _findInLine(term: string, row: number, col: number, searchOptions: ISearchOptions = {}, isReverseSearch: boolean = false): ISearchResult {
|
||||
|
||||
// Ignore wrapped lines, only consider on unwrapped line (first row of command string).
|
||||
if (this._terminal._core.buffer.lines.get(row).isWrapped) {
|
||||
if (this._terminal.buffer.getLine(row).isWrapped) {
|
||||
return;
|
||||
}
|
||||
let stringLine = this._linesCache ? this._linesCache[row] : void 0;
|
||||
@@ -282,18 +282,18 @@ export class SearchHelper implements ISearchHelper {
|
||||
return;
|
||||
}
|
||||
|
||||
const line = this._terminal._core.buffer.lines.get(row);
|
||||
const line = this._terminal.buffer.getLine(row);
|
||||
|
||||
for (let i = 0; i < resultIndex; i++) {
|
||||
const charData = line.get(i);
|
||||
const cell = line.getCell(i);
|
||||
// Adjust the searchIndex to normalize emoji into single chars
|
||||
const char = charData[1/*CHAR_DATA_CHAR_INDEX*/];
|
||||
const char = cell.char;
|
||||
if (char.length > 1) {
|
||||
resultIndex -= char.length - 1;
|
||||
}
|
||||
// Adjust the searchIndex for empty characters following wide unicode
|
||||
// chars (eg. CJK)
|
||||
const charWidth = charData[2/*CHAR_DATA_WIDTH_INDEX*/];
|
||||
const charWidth = cell.width;
|
||||
if (charWidth === 0) {
|
||||
resultIndex++;
|
||||
}
|
||||
@@ -318,9 +318,9 @@ export class SearchHelper implements ISearchHelper {
|
||||
let lineWrapsToNext: boolean;
|
||||
|
||||
do {
|
||||
const nextLine = this._terminal._core.buffer.lines.get(lineIndex + 1);
|
||||
const nextLine = this._terminal.buffer.getLine(lineIndex + 1);
|
||||
lineWrapsToNext = nextLine ? nextLine.isWrapped : false;
|
||||
lineString += this._terminal._core.buffer.translateBufferLineToString(lineIndex, !lineWrapsToNext && trimRight).substring(0, this._terminal.cols);
|
||||
lineString += this._terminal.buffer.getLine(lineIndex).translateToString(!lineWrapsToNext && trimRight).substring(0, this._terminal.cols);
|
||||
lineIndex++;
|
||||
} while (lineWrapsToNext);
|
||||
|
||||
@@ -338,7 +338,7 @@ export class SearchHelper implements ISearchHelper {
|
||||
return false;
|
||||
}
|
||||
this._terminal.select(result.col, result.row, result.term.length);
|
||||
this._terminal.scrollLines(result.row - this._terminal._core.buffer.ydisp);
|
||||
this._terminal.scrollLines(result.row - this._terminal.buffer.viewportY);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,11 +23,56 @@ class MockTerminal {
|
||||
get core(): any {
|
||||
return this._core;
|
||||
}
|
||||
get buffer(): IBuffer {
|
||||
// TODO: This is a hacky workaround until we use puppeteer for addon tests
|
||||
const buffer = this._core.buffer;
|
||||
return {
|
||||
cursorY: buffer.y,
|
||||
cursorX: buffer.x,
|
||||
viewportY: buffer.ydisp,
|
||||
baseY: buffer.ybase,
|
||||
length: buffer.length,
|
||||
getLine(y: number): IBufferLine {
|
||||
return {
|
||||
isWrapped: buffer.lines.get(y) ? buffer.lines.get(y).isWrapped : false,
|
||||
getCell(x: number): IBufferCell {
|
||||
return {
|
||||
char: buffer.lines.get(y).get(x)[1/*CHAR_DATA_CHAR_INDEX*/],
|
||||
width: buffer.lines.get(y).get(x)[2/*CHAR_DATA_WIDTH_INDEX*/]
|
||||
};
|
||||
},
|
||||
translateToString(trimRight?: boolean, startColumn?: number, endColumn?: number): string {
|
||||
return buffer.translateBufferLineToString(y, trimRight);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
pushWriteData(): void {
|
||||
this._core._innerWrite();
|
||||
}
|
||||
}
|
||||
|
||||
interface IBuffer {
|
||||
readonly cursorY: number;
|
||||
readonly cursorX: number;
|
||||
readonly viewportY: number;
|
||||
readonly baseY: number;
|
||||
readonly length: number;
|
||||
getLine(y: number): IBufferLine | undefined;
|
||||
}
|
||||
|
||||
interface IBufferLine {
|
||||
readonly isWrapped: boolean;
|
||||
getCell(x: number): IBufferCell;
|
||||
translateToString(trimRight?: boolean, startColumn?: number, endColumn?: number): string;
|
||||
}
|
||||
|
||||
interface IBufferCell {
|
||||
readonly char: string;
|
||||
readonly width: number;
|
||||
}
|
||||
|
||||
class TestSearchHelper extends SearchHelper {
|
||||
public findInLine(term: string, rowNumber: number, searchOptions?: ISearchOptions): ISearchResult {
|
||||
return this._findInLine(term, rowNumber, 0, searchOptions);
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { assert } from 'chai';
|
||||
import { AddonManager, ILoadedAddon } from './AddonManager';
|
||||
import { ITerminalAddon } from 'xterm';
|
||||
|
||||
class TestAddonManager extends AddonManager {
|
||||
public get addons(): ILoadedAddon[] {
|
||||
return this._addons;
|
||||
}
|
||||
}
|
||||
|
||||
describe('AddonManager', () => {
|
||||
let manager: TestAddonManager;
|
||||
|
||||
beforeEach(() => {
|
||||
manager = new TestAddonManager();
|
||||
});
|
||||
|
||||
describe('loadAddon', () => {
|
||||
it('should call addon constructor', () => {
|
||||
let called = false;
|
||||
class Addon implements ITerminalAddon {
|
||||
activate(terminal: any): void {
|
||||
assert.equal(terminal, 'foo', 'The first constructor arg should be Terminal');
|
||||
called = true;
|
||||
}
|
||||
dispose(): void { }
|
||||
}
|
||||
manager.loadAddon('foo' as any, new Addon());
|
||||
assert.equal(called, true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('dispose', () => {
|
||||
it('should dispose all loaded addons', () => {
|
||||
let called = 0;
|
||||
class Addon implements ITerminalAddon {
|
||||
activate(): void {}
|
||||
dispose(): void { called++; }
|
||||
}
|
||||
manager.loadAddon(null, new Addon());
|
||||
manager.loadAddon(null, new Addon());
|
||||
manager.loadAddon(null, new Addon());
|
||||
assert.equal(manager.addons.length, 3);
|
||||
manager.dispose();
|
||||
assert.equal(called, 3);
|
||||
assert.equal(manager.addons.length, 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { ITerminalAddon, IDisposable, Terminal } from 'xterm';
|
||||
|
||||
export interface ILoadedAddon {
|
||||
instance: ITerminalAddon;
|
||||
dispose: () => void;
|
||||
isDisposed: boolean;
|
||||
}
|
||||
|
||||
export class AddonManager implements IDisposable {
|
||||
protected _addons: ILoadedAddon[] = [];
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
for (let i = this._addons.length - 1; i >= 0; i--) {
|
||||
this._addons[i].instance.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public loadAddon(terminal: Terminal, instance: ITerminalAddon): void {
|
||||
const loadedAddon: ILoadedAddon = {
|
||||
instance,
|
||||
dispose: instance.dispose,
|
||||
isDisposed: false
|
||||
};
|
||||
this._addons.push(loadedAddon);
|
||||
instance.dispose = () => this._wrappedAddonDispose(loadedAddon);
|
||||
instance.activate(<any>terminal);
|
||||
}
|
||||
|
||||
private _wrappedAddonDispose(loadedAddon: ILoadedAddon): void {
|
||||
if (loadedAddon.isDisposed) {
|
||||
// Do nothing if already disposed
|
||||
return;
|
||||
}
|
||||
let index = -1;
|
||||
for (let i = 0; i < this._addons.length; i++) {
|
||||
if (this._addons[i] === loadedAddon) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (index === -1) {
|
||||
throw new Error('Could not dispose an addon that has not been loaded');
|
||||
}
|
||||
loadedAddon.isDisposed = true;
|
||||
loadedAddon.dispose();
|
||||
this._addons.splice(index, 1);
|
||||
}
|
||||
}
|
||||
@@ -135,6 +135,52 @@ describe('API Integration Tests', () => {
|
||||
assert.equal(await page.evaluate(`document.activeElement.className`), '');
|
||||
});
|
||||
|
||||
describe('loadAddon', () => {
|
||||
it('constructor', async function(): Promise<any> {
|
||||
this.timeout(10000);
|
||||
await openTerminal({ cols: 5 });
|
||||
await page.evaluate(`
|
||||
window.cols = 0;
|
||||
window.term.loadAddon({
|
||||
activate: (t) => window.cols = t.cols,
|
||||
dispose: () => {}
|
||||
});
|
||||
`);
|
||||
assert.equal(await page.evaluate(`window.cols`), 5);
|
||||
});
|
||||
|
||||
it('dispose (addon)', async function(): Promise<any> {
|
||||
this.timeout(10000);
|
||||
await openTerminal();
|
||||
await page.evaluate(`
|
||||
window.disposeCalled = false
|
||||
window.addon = {
|
||||
activate: () => {},
|
||||
dispose: () => window.disposeCalled = true
|
||||
};
|
||||
window.term.loadAddon(window.addon);
|
||||
`);
|
||||
assert.equal(await page.evaluate(`window.disposeCalled`), false);
|
||||
await page.evaluate(`window.addon.dispose()`);
|
||||
assert.equal(await page.evaluate(`window.disposeCalled`), true);
|
||||
});
|
||||
|
||||
it('dispose (terminal)', async function(): Promise<any> {
|
||||
this.timeout(10000);
|
||||
await openTerminal();
|
||||
await page.evaluate(`
|
||||
window.disposeCalled = false
|
||||
window.term.loadAddon({
|
||||
activate: () => {},
|
||||
dispose: () => window.disposeCalled = true
|
||||
});
|
||||
`);
|
||||
assert.equal(await page.evaluate(`window.disposeCalled`), false);
|
||||
await page.evaluate(`window.term.dispose()`);
|
||||
assert.equal(await page.evaluate(`window.disposeCalled`), true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Events', () => {
|
||||
it('onCursorMove', async function(): Promise<any> {
|
||||
this.timeout(10000);
|
||||
|
||||
@@ -7,7 +7,7 @@ import { assert } from 'chai';
|
||||
import { Terminal } from './Terminal';
|
||||
import * as attach from '../addons/attach/attach';
|
||||
|
||||
describe('Terminal', () => {
|
||||
describe('Terminal', () => {
|
||||
it('should apply addons with Terminal.applyAddon', () => {
|
||||
Terminal.applyAddon(attach);
|
||||
// Test that addon was applied successfully, adding attach to Terminal's
|
||||
|
||||
@@ -3,18 +3,21 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { Terminal as ITerminalApi, ITerminalOptions, IMarker, IDisposable, ILinkMatcherOptions, ITheme, ILocalizableStrings, IBuffer as IBufferApi, IBufferLine as IBufferLineApi, IBufferCell as IBufferCellApi, ISelectionPosition } from 'xterm';
|
||||
import { Terminal as ITerminalApi, ITerminalOptions, IMarker, IDisposable, ILinkMatcherOptions, ITheme, ILocalizableStrings, ITerminalAddon, ISelectionPosition, IBuffer as IBufferApi, IBufferLine as IBufferLineApi, IBufferCell as IBufferCellApi } from 'xterm';
|
||||
import { ITerminal, IBuffer } from '../Types';
|
||||
import { IBufferLine } from '../core/Types';
|
||||
import { Terminal as TerminalCore } from '../Terminal';
|
||||
import * as Strings from '../Strings';
|
||||
import { IEvent } from '../common/EventEmitter2';
|
||||
import { AddonManager } from './AddonManager';
|
||||
|
||||
export class Terminal implements ITerminalApi {
|
||||
private _core: ITerminal;
|
||||
private _addonManager: AddonManager;
|
||||
|
||||
constructor(options?: ITerminalOptions) {
|
||||
this._core = new TerminalCore(options);
|
||||
this._addonManager = new AddonManager();
|
||||
}
|
||||
|
||||
public get onCursorMove(): IEvent<void> { return this._core.onCursorMove; }
|
||||
@@ -115,6 +118,7 @@ export class Terminal implements ITerminalApi {
|
||||
this._core.selectLines(start, end);
|
||||
}
|
||||
public dispose(): void {
|
||||
this._addonManager.dispose();
|
||||
this._core.dispose();
|
||||
}
|
||||
public destroy(): void {
|
||||
@@ -176,6 +180,9 @@ export class Terminal implements ITerminalApi {
|
||||
public static applyAddon(addon: any): void {
|
||||
addon.apply(Terminal);
|
||||
}
|
||||
public loadAddon(addon: ITerminalAddon): void {
|
||||
return this._addonManager.loadAddon(this, addon);
|
||||
}
|
||||
public static get strings(): ILocalizableStrings {
|
||||
return Strings;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user