Merge branch 'master' into utf8_input
This commit is contained in:
+50
-2
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { Terminal as PublicTerminal, ITerminalOptions as IPublicTerminalOptions, IEventEmitter, IDisposable } from 'xterm';
|
||||
import { ITerminalOptions as IPublicTerminalOptions, IEventEmitter, IDisposable, IMarker } from 'xterm';
|
||||
import { IColorSet, IRenderer } from './renderer/Types';
|
||||
import { ICharset, IAttributeData, ICellData, IBufferLine, CharData } from './core/Types';
|
||||
import { ICircularList } from './common/Types';
|
||||
@@ -196,7 +196,7 @@ export interface ILinkifierEvent {
|
||||
fg: number;
|
||||
}
|
||||
|
||||
export interface ITerminal extends PublicTerminal, IElementAccessor, IBufferAccessor, ILinkifierAccessor {
|
||||
export interface ITerminal extends IPublicTerminal, IElementAccessor, IBufferAccessor, ILinkifierAccessor {
|
||||
screenElement: HTMLElement;
|
||||
selectionManager: ISelectionManager;
|
||||
charMeasure: ICharMeasure;
|
||||
@@ -221,6 +221,54 @@ export interface ITerminal extends PublicTerminal, IElementAccessor, IBufferAcce
|
||||
showCursor(): void;
|
||||
}
|
||||
|
||||
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;
|
||||
clearSelection(): 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;
|
||||
getOption(key: string): any;
|
||||
setOption(key: string, value: any): void;
|
||||
refresh(start: number, end: number): void;
|
||||
reset(): void;
|
||||
}
|
||||
|
||||
export interface IBufferAccessor {
|
||||
buffer: IBuffer;
|
||||
}
|
||||
|
||||
+128
-6
@@ -48,7 +48,7 @@ describe('API Integration Tests', () => {
|
||||
window.term.write('foo');
|
||||
window.term.write('bar');
|
||||
`);
|
||||
assert.equal(await page.evaluate(`window.term._core.buffer.translateBufferLineToString(0, true)`), 'foobar');
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).translateToString(true)`), 'foobar');
|
||||
});
|
||||
|
||||
it('writeln', async function(): Promise<any> {
|
||||
@@ -58,8 +58,8 @@ describe('API Integration Tests', () => {
|
||||
window.term.writeln('foo');
|
||||
window.term.writeln('bar');
|
||||
`);
|
||||
assert.equal(await page.evaluate(`window.term._core.buffer.translateBufferLineToString(0, true)`), 'foo');
|
||||
assert.equal(await page.evaluate(`window.term._core.buffer.translateBufferLineToString(1, true)`), 'bar');
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).translateToString(true)`), 'foo');
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(1).translateToString(true)`), 'bar');
|
||||
});
|
||||
|
||||
it('clear', async function(): Promise<any> {
|
||||
@@ -72,10 +72,10 @@ describe('API Integration Tests', () => {
|
||||
}
|
||||
`);
|
||||
await page.evaluate(`window.term.clear()`);
|
||||
assert.equal(await page.evaluate(`window.term._core.buffer.lines.length`), '5');
|
||||
assert.equal(await page.evaluate(`window.term._core.buffer.translateBufferLineToString(0, true)`), 'test9');
|
||||
assert.equal(await page.evaluate(`window.term.buffer.length`), '5');
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).translateToString(true)`), 'test9');
|
||||
for (let i = 1; i < 5; i++) {
|
||||
assert.equal(await page.evaluate(`window.term._core.buffer.translateBufferLineToString(${i}, true)`), '');
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(${i}).translateToString(true)`), '');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -231,6 +231,128 @@ describe('API Integration Tests', () => {
|
||||
assert.deepEqual(await page.evaluate(`window.calls`), ['foo']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('buffer', () => {
|
||||
it('cursorX, cursorY', async function(): Promise<any> {
|
||||
this.timeout(10000);
|
||||
await openTerminal({ rows: 5, cols: 5 });
|
||||
assert.equal(await page.evaluate(`window.term.buffer.cursorX`), 0);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.cursorY`), 0);
|
||||
await page.evaluate(`window.term.write('foo')`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.cursorX`), 3);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.cursorY`), 0);
|
||||
await page.evaluate(`window.term.write('\\n')`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.cursorX`), 3);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.cursorY`), 1);
|
||||
await page.evaluate(`window.term.write('\\r')`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.cursorX`), 0);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.cursorY`), 1);
|
||||
await page.evaluate(`window.term.write('abcde')`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.cursorX`), 5);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.cursorY`), 1);
|
||||
await page.evaluate(`window.term.write('\\n\\r\\n\\n\\n\\n\\n')`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.cursorX`), 0);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.cursorY`), 4);
|
||||
});
|
||||
|
||||
it('viewportY', async function(): Promise<any> {
|
||||
this.timeout(10000);
|
||||
await openTerminal({ rows: 5 });
|
||||
assert.equal(await page.evaluate(`window.term.buffer.viewportY`), 0);
|
||||
await page.evaluate(`window.term.write('\\n\\n\\n\\n')`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.viewportY`), 0);
|
||||
await page.evaluate(`window.term.write('\\n')`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.viewportY`), 1);
|
||||
await page.evaluate(`window.term.write('\\n\\n\\n\\n')`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.viewportY`), 5);
|
||||
await page.evaluate(`window.term.scrollLines(-1)`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.viewportY`), 4);
|
||||
await page.evaluate(`window.term.scrollToTop()`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.viewportY`), 0);
|
||||
});
|
||||
|
||||
it('baseY', async function(): Promise<any> {
|
||||
this.timeout(10000);
|
||||
await openTerminal({ rows: 5 });
|
||||
assert.equal(await page.evaluate(`window.term.buffer.baseY`), 0);
|
||||
await page.evaluate(`window.term.write('\\n\\n\\n\\n')`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.baseY`), 0);
|
||||
await page.evaluate(`window.term.write('\\n')`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.baseY`), 1);
|
||||
await page.evaluate(`window.term.write('\\n\\n\\n\\n')`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.baseY`), 5);
|
||||
await page.evaluate(`window.term.scrollLines(-1)`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.baseY`), 5);
|
||||
await page.evaluate(`window.term.scrollToTop()`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.baseY`), 5);
|
||||
});
|
||||
|
||||
it('length', async function(): Promise<any> {
|
||||
this.timeout(10000);
|
||||
await openTerminal({ rows: 5 });
|
||||
assert.equal(await page.evaluate(`window.term.buffer.length`), 5);
|
||||
await page.evaluate(`window.term.write('\\n\\n\\n\\n')`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.length`), 5);
|
||||
await page.evaluate(`window.term.write('\\n')`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.length`), 6);
|
||||
await page.evaluate(`window.term.write('\\n\\n\\n\\n')`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.length`), 10);
|
||||
});
|
||||
|
||||
describe('getLine', () => {
|
||||
it('invalid index', async function(): Promise<any> {
|
||||
this.timeout(10000);
|
||||
await openTerminal({ rows: 5 });
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(-1)`), undefined);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(5)`), undefined);
|
||||
});
|
||||
|
||||
it('isWrapped', async function(): Promise<any> {
|
||||
this.timeout(10000);
|
||||
await openTerminal({ cols: 5 });
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).isWrapped`), false);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(1).isWrapped`), false);
|
||||
await page.evaluate(`window.term.write('abcde')`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).isWrapped`), false);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(1).isWrapped`), false);
|
||||
await page.evaluate(`window.term.write('f')`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).isWrapped`), false);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(1).isWrapped`), true);
|
||||
});
|
||||
|
||||
it('translateToString', async function(): Promise<any> {
|
||||
this.timeout(10000);
|
||||
await openTerminal({ cols: 5 });
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).translateToString()`), ' ');
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).translateToString(true)`), '');
|
||||
await page.evaluate(`window.term.write('foo')`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).translateToString()`), 'foo ');
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).translateToString(true)`), 'foo');
|
||||
await page.evaluate(`window.term.write('bar')`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).translateToString()`), 'fooba');
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).translateToString(true)`), 'fooba');
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(1).translateToString(true)`), 'r');
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).translateToString(false, 1)`), 'ooba');
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).translateToString(false, 1, 3)`), 'oo');
|
||||
});
|
||||
|
||||
it('getCell', async function(): Promise<any> {
|
||||
this.timeout(10000);
|
||||
await openTerminal({ cols: 5 });
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).getCell(-1)`), undefined);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).getCell(5)`), undefined);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).getCell(0).char`), '');
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).getCell(0).width`), 1);
|
||||
await page.evaluate(`window.term.write('a文')`);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).getCell(0).char`), 'a');
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).getCell(0).width`), 1);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).getCell(1).char`), '文');
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).getCell(1).width`), 2);
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).getCell(2).char`), '');
|
||||
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).getCell(2).width`), 0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
async function openTerminal(options: ITerminalOptions = {}): Promise<void> {
|
||||
|
||||
+42
-2
@@ -3,8 +3,9 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { Terminal as ITerminalApi, ITerminalOptions, IMarker, IDisposable, ILinkMatcherOptions, ITheme, ILocalizableStrings } from 'xterm';
|
||||
import { ITerminal } from '../Types';
|
||||
import { Terminal as ITerminalApi, ITerminalOptions, IMarker, IDisposable, ILinkMatcherOptions, ITheme, ILocalizableStrings, 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';
|
||||
@@ -30,6 +31,7 @@ export class Terminal implements ITerminalApi {
|
||||
public get textarea(): HTMLTextAreaElement { return this._core.textarea; }
|
||||
public get rows(): number { return this._core.rows; }
|
||||
public get cols(): number { return this._core.cols; }
|
||||
public get buffer(): IBufferApi { return new BufferApiView(this._core.buffer); }
|
||||
public get markers(): ReadonlyArray<IMarker> { return this._core.markers; }
|
||||
public blur(): void {
|
||||
this._core.blur();
|
||||
@@ -172,3 +174,41 @@ export class Terminal implements ITerminalApi {
|
||||
return Strings;
|
||||
}
|
||||
}
|
||||
|
||||
class BufferApiView implements IBufferApi {
|
||||
constructor(private _buffer: IBuffer) {}
|
||||
|
||||
public get cursorY(): number { return this._buffer.y; }
|
||||
public get cursorX(): number { return this._buffer.x; }
|
||||
public get viewportY(): number { return this._buffer.ydisp; }
|
||||
public get baseY(): number { return this._buffer.ybase; }
|
||||
public get length(): number { return this._buffer.lines.length; }
|
||||
public getLine(y: number): IBufferLineApi | undefined {
|
||||
const line = this._buffer.lines.get(y);
|
||||
if (!line) {
|
||||
return undefined;
|
||||
}
|
||||
return new BufferLineApiView(line);
|
||||
}
|
||||
}
|
||||
|
||||
class BufferLineApiView implements IBufferLineApi {
|
||||
constructor(private _line: IBufferLine) {}
|
||||
|
||||
public get isWrapped(): boolean { return this._line.isWrapped; }
|
||||
public getCell(x: number): IBufferCellApi | undefined {
|
||||
if (x < 0 || x >= this._line.length) {
|
||||
return undefined;
|
||||
}
|
||||
return new BufferCellApiView(this._line, x);
|
||||
}
|
||||
public translateToString(trimRight?: boolean, startColumn?: number, endColumn?: number): string {
|
||||
return this._line.translateToString(trimRight, startColumn, endColumn);
|
||||
}
|
||||
}
|
||||
|
||||
class BufferCellApiView implements IBufferCellApi {
|
||||
constructor(private _line: IBufferLine, private _x: number) {}
|
||||
public get char(): string { return this._line.getString(this._x); }
|
||||
public get width(): number { return this._line.getWidth(this._x); }
|
||||
}
|
||||
|
||||
@@ -157,8 +157,8 @@ export class DomRenderer extends Disposable implements IRenderer {
|
||||
`${this._terminalSelector} .${ROW_CONTAINER_CLASS} {` +
|
||||
` color: ${this.colorManager.colors.foreground.css};` +
|
||||
` background-color: ${this.colorManager.colors.background.css};` +
|
||||
` font-family: ${this._terminal.getOption('fontFamily')};` +
|
||||
` font-size: ${this._terminal.getOption('fontSize')}px;` +
|
||||
` font-family: ${this._terminal.options.fontFamily};` +
|
||||
` font-size: ${this._terminal.options.fontSize}px;` +
|
||||
`}`;
|
||||
// Text styles
|
||||
styles +=
|
||||
|
||||
Reference in New Issue
Block a user