Remove Terminal dependency from InputHandler 🎉

This commit is contained in:
Daniel Imms
2020-04-26 06:46:37 -07:00
parent dbced5c1a4
commit ba40fe4ff4
5 changed files with 27 additions and 75 deletions
+10 -19
View File
@@ -5,7 +5,7 @@
import { assert, expect } from 'chai';
import { InputHandler } from './InputHandler';
import { MockInputHandlingTerminal, TestTerminal } from './TestUtils.test';
import { TestTerminal } from './TestUtils.test';
import { Terminal } from './Terminal';
import { IBufferLine, IAttributeData } from 'common/Types';
import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine';
@@ -39,12 +39,11 @@ class TestInputHandler extends InputHandler {
describe('InputHandler', () => {
describe('save and restore cursor', () => {
const terminal = new MockInputHandlingTerminal();
const bufferService = new MockBufferService(80, 30);
bufferService.buffer.x = 1;
bufferService.buffer.y = 2;
bufferService.buffer.ybase = 0;
const inputHandler = new TestInputHandler(terminal, bufferService, new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService(), new MockUnicodeService(), {} as any);
const inputHandler = new TestInputHandler(bufferService, new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService(), new MockUnicodeService(), {} as any);
inputHandler.curAttrData.fg = 3;
// Save cursor position
inputHandler.saveCursor();
@@ -64,7 +63,7 @@ describe('InputHandler', () => {
describe('setCursorStyle', () => {
it('should call Terminal.setOption with correct params', () => {
const optionsService = new MockOptionsService();
const inputHandler = new InputHandler(new MockInputHandlingTerminal(), new MockBufferService(80, 30), new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), optionsService, new MockCoreMouseService(), new MockUnicodeService(), {} as any);
const inputHandler = new InputHandler(new MockBufferService(80, 30), new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), optionsService, new MockCoreMouseService(), new MockUnicodeService(), {} as any);
inputHandler.setCursorStyle(Params.fromArray([0]));
assert.equal(optionsService.options['cursorStyle'], 'block');
@@ -103,9 +102,8 @@ describe('InputHandler', () => {
});
describe('setMode', () => {
it('should toggle bracketedPasteMode', () => {
const terminal = new MockInputHandlingTerminal();
const coreService = new MockCoreService();
const inputHandler = new InputHandler(terminal, new MockBufferService(80, 30), new MockCharsetService(), coreService, new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService(), new MockUnicodeService(), {} as any);
const inputHandler = new InputHandler(new MockBufferService(80, 30), new MockCharsetService(), coreService, new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService(), new MockUnicodeService(), {} as any);
// Set bracketed paste mode
inputHandler.setModePrivate(Params.fromArray([2004]));
assert.equal(coreService.decPrivateModes.bracketedPasteMode, true);
@@ -122,9 +120,8 @@ describe('InputHandler', () => {
}
it('insertChars', function(): void {
const term = new Terminal();
const bufferService = new MockBufferService(80, 30);
const inputHandler = new InputHandler(term, bufferService, new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService(), new MockUnicodeService(), {} as any);
const inputHandler = new InputHandler(bufferService, new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService(), new MockUnicodeService(), {} as any);
// insert some data in first and second line
inputHandler.parse(Array(bufferService.cols - 9).join('a'));
@@ -160,9 +157,8 @@ describe('InputHandler', () => {
expect(line1.translateToString(true)).equals(Array(bufferService.cols - 9).join('a'));
});
it('deleteChars', function(): void {
const term = new Terminal();
const bufferService = new MockBufferService(80, 30);
const inputHandler = new InputHandler(term, bufferService, new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService(), new MockUnicodeService(), {} as any);
const inputHandler = new InputHandler(bufferService, new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService(), new MockUnicodeService(), {} as any);
// insert some data in first and second line
inputHandler.parse(Array(bufferService.cols - 9).join('a'));
@@ -201,9 +197,8 @@ describe('InputHandler', () => {
expect(line1.translateToString(true)).equals(Array(bufferService.cols - 9).join('a'));
});
it('eraseInLine', function(): void {
const term = new Terminal();
const bufferService = new MockBufferService(80, 30);
const inputHandler = new InputHandler(term, bufferService, new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService(), new MockUnicodeService(), {} as any);
const inputHandler = new InputHandler(bufferService, new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService(), new MockUnicodeService(), {} as any);
// fill 6 lines to test 3 different states
inputHandler.parse(Array(bufferService.cols + 1).join('a'));
@@ -230,9 +225,8 @@ describe('InputHandler', () => {
});
it('eraseInDisplay', function(): void {
const term = new Terminal({cols: 80, rows: 7});
const bufferService = new MockBufferService(80, 7);
const inputHandler = new InputHandler(term, bufferService, new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService(), new MockUnicodeService(), {} as any);
const inputHandler = new InputHandler(bufferService, new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService(), new MockUnicodeService(), {} as any);
// fill display with a's
for (let i = 0; i < bufferService.rows; ++i) inputHandler.parse(Array(bufferService.cols + 1).join('a'));
@@ -366,8 +360,7 @@ describe('InputHandler', () => {
});
describe('print', () => {
it('should not cause an infinite loop (regression test)', () => {
const term = new Terminal();
const inputHandler = new InputHandler(term, new MockBufferService(80, 30), new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService(), new MockUnicodeService(), {} as any);
const inputHandler = new InputHandler(new MockBufferService(80, 30), new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService(), new MockUnicodeService(), {} as any);
const container = new Uint32Array(10);
container[0] = 0x200B;
inputHandler.print(container, 0, 1);
@@ -375,14 +368,12 @@ describe('InputHandler', () => {
});
describe('alt screen', () => {
let term: Terminal;
let bufferService: IBufferService;
let handler: InputHandler;
beforeEach(() => {
term = new Terminal();
bufferService = new MockBufferService(80, 30);
handler = new InputHandler(term, bufferService, new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService(), new MockUnicodeService(), {} as any);
handler = new InputHandler(bufferService, new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService(), new MockUnicodeService(), {} as any);
});
it('should handle DECSET/DECRST 47 (alt screen buffer)', () => {
handler.parse('\x1b[?47h\r\n\x1b[31mJUNK\x1b[?47lTEST');
+12 -11
View File
@@ -4,7 +4,7 @@
* @license MIT
*/
import { IInputHandler, IInputHandlingTerminal } from './Types';
import { IInputHandler } from './Types';
import { C0, C1 } from 'common/data/EscapeSequences';
import { CHARSETS, DEFAULT_CHARSET } from 'common/data/Charsets';
import { EscapeSequenceParser } from 'common/parser/EscapeSequenceParser';
@@ -238,6 +238,8 @@ export class InputHandler extends Disposable implements IInputHandler {
public get onScroll(): IEvent<number> { return this._onScroll.event; }
private _onScrollRequest = new EventEmitter<IAttributeData, boolean | void>();
public get onScrollRequest(): IEvent<IAttributeData, boolean | void> { return this._onScrollRequest.event; }
private _onSyncScrollBarRequest = new EventEmitter<void>();
public get onSyncScrollBarRequest(): IEvent<void> { return this._onSyncScrollBarRequest.event; }
private _onTitleChange = new EventEmitter<string>();
public get onTitleChange(): IEvent<string> { return this._onTitleChange.event; }
private _onA11yChar = new EventEmitter<string>();
@@ -246,7 +248,6 @@ export class InputHandler extends Disposable implements IInputHandler {
public get onA11yTab(): IEvent<number> { return this._onA11yTab.event; }
constructor(
private _terminal: IInputHandlingTerminal,
private readonly _bufferService: IBufferService,
private readonly _charsetService: ICharsetService,
private readonly _coreService: ICoreService,
@@ -256,8 +257,8 @@ export class InputHandler extends Disposable implements IInputHandler {
private readonly _coreMouseService: ICoreMouseService,
private readonly _unicodeService: IUnicodeService,
private readonly _instantiationService: IInstantiationService,
private readonly _parser: IEscapeSequenceParser = new EscapeSequenceParser())
{
private readonly _parser: IEscapeSequenceParser = new EscapeSequenceParser()
) {
super();
this.register(this._parser);
@@ -1766,7 +1767,7 @@ export class InputHandler extends Disposable implements IInputHandler {
case 66:
this._logService.debug('Serial port requested application keypad.');
this._coreService.decPrivateModes.applicationKeypad = true;
this._terminal.viewport?.syncScrollArea();
this._onSyncScrollBarRequest.fire();
break;
case 9: // X10 Mouse
// no release, no motion, no wheel, no modifiers.
@@ -1812,7 +1813,7 @@ export class InputHandler extends Disposable implements IInputHandler {
this._bufferService.buffers.activateAltBuffer(this._eraseAttrData());
this._coreService.isCursorInitialized = true;
this._onRequestRefreshRows.fire(0, this._bufferService.rows - 1);
this._terminal.viewport?.syncScrollArea();
this._onSyncScrollBarRequest.fire();
break;
case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)
this._coreService.decPrivateModes.bracketedPasteMode = true;
@@ -1993,7 +1994,7 @@ export class InputHandler extends Disposable implements IInputHandler {
case 66:
this._logService.debug('Switching back to normal keypad.');
this._coreService.decPrivateModes.applicationKeypad = false;
this._terminal.viewport?.syncScrollArea();
this._onSyncScrollBarRequest.fire();
break;
case 9: // X10 Mouse
case 1000: // vt200 mouse
@@ -2030,7 +2031,7 @@ export class InputHandler extends Disposable implements IInputHandler {
}
this._coreService.isCursorInitialized = true;
this._onRequestRefreshRows.fire(0, this._bufferService.rows - 1);
this._terminal.viewport?.syncScrollArea();
this._onSyncScrollBarRequest.fire();
break;
case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)
this._coreService.decPrivateModes.bracketedPasteMode = false;
@@ -2369,7 +2370,7 @@ export class InputHandler extends Disposable implements IInputHandler {
*/
public softReset(params: IParams): void {
this._coreService.isCursorHidden = false;
this._terminal.viewport?.syncScrollArea();
this._onSyncScrollBarRequest.fire();
this._bufferService.buffer.scrollTop = 0;
this._bufferService.buffer.scrollBottom = this._bufferService.rows - 1;
this._curAttrData = DEFAULT_ATTR_DATA.clone();
@@ -2617,7 +2618,7 @@ export class InputHandler extends Disposable implements IInputHandler {
public keypadApplicationMode(): void {
this._logService.debug('Serial port requested application keypad.');
this._coreService.decPrivateModes.applicationKeypad = true;
this._terminal.viewport?.syncScrollArea();
this._onSyncScrollBarRequest.fire();
}
/**
@@ -2628,7 +2629,7 @@ export class InputHandler extends Disposable implements IInputHandler {
public keypadNumericMode(): void {
this._logService.debug('Switching back to normal keypad.');
this._coreService.decPrivateModes.applicationKeypad = false;
this._terminal.viewport?.syncScrollArea();
this._onSyncScrollBarRequest.fire();
}
/**
+4 -25
View File
@@ -21,7 +21,7 @@
* http://linux.die.net/man/7/urxvt
*/
import { IInputHandlingTerminal, ICompositionHelper, ITerminal, IBrowser, CustomKeyEventHandler } from './Types';
import { ICompositionHelper, ITerminal, IBrowser, CustomKeyEventHandler } from './Types';
import { IRenderer, CharacterJoinerHandler } from 'browser/renderer/Types';
import { CompositionHelper } from 'browser/input/CompositionHelper';
import { Viewport } from 'browser/Viewport';
@@ -60,7 +60,7 @@ import { CoreTerminal } from 'common/CoreTerminal';
const document = (typeof window !== 'undefined') ? window.document : null;
export class Terminal extends CoreTerminal implements ITerminal, IInputHandlingTerminal {
export class Terminal extends CoreTerminal implements ITerminal {
public textarea: HTMLTextAreaElement;
public element: HTMLElement;
public screenElement: HTMLElement;
@@ -176,7 +176,7 @@ export class Terminal extends CoreTerminal implements ITerminal, IInputHandlingT
this._inputHandler.reset();
} else {
// Register input handler and refire/handle events
this._inputHandler = new InputHandler(this, this._bufferService, this._charsetService, this._coreService, this._dirtyRowService, this._logService, this.optionsService, this._coreMouseService, this.unicodeService, this._instantiationService);
this._inputHandler = new InputHandler(this._bufferService, this._charsetService, this._coreService, this._dirtyRowService, this._logService, this.optionsService, this._coreMouseService, this.unicodeService, this._instantiationService);
this.register(this._inputHandler.onRequestBell(() => this.bell()));
this.register(this._inputHandler.onRequestRefreshRows((start, end) => this.refresh(start, end)));
this.register(this._inputHandler.onRequestReset(() => this.reset()));
@@ -462,6 +462,7 @@ export class Terminal extends CoreTerminal implements ITerminal, IInputHandlingT
this._viewportScrollArea
);
this.viewport.onThemeChange(this._colorManager.colors);
this.register(this._inputHandler.onSyncScrollBarRequest(() => this.viewport.syncScrollArea()));
this.register(this.viewport);
this.register(this.onCursorMove(() => this._renderService.onCursorMove()));
@@ -1316,28 +1317,6 @@ export class Terminal extends CoreTerminal implements ITerminal, IInputHandlingT
this._onScroll.fire(this.buffer.ydisp);
}
/**
* Emit the data event and populate the given data.
* @param data The data to populate in the event.
*/
// public handler(data: string): void {
// // Prevents all events to pty process if stdin is disabled
// if (this.options.disableStdin) {
// return;
// }
// // Clear the selection if the selection manager is available and has an active selection
// if (this.selectionService && this.selectionService.hasSelection) {
// this.selectionService.clearSelection();
// }
// // Input is being sent to the terminal, the terminal should focus the prompt.
// if (this.buffer.ybase !== this.buffer.ydisp) {
// this.scrollToBottom();
// }
// this._onData.fire(data);
// }
/**
* Reset terminal.
* Note: Calling this directly from JS is synchronous but does not clear
+1 -11
View File
@@ -4,7 +4,7 @@
*/
import { IRenderer, IRenderDimensions, CharacterJoinerHandler, IRequestRedrawEvent } from 'browser/renderer/Types';
import { IInputHandlingTerminal, ICompositionHelper, ITerminal, IBrowser } from './Types';
import { ICompositionHelper, ITerminal, IBrowser } from './Types';
import { IBuffer, IBufferStringIterator, IBufferSet } from 'common/buffer/Types';
import { IBufferLine, ICellData, IAttributeData, ICircularList, XtermListener, ICharset, ITerminalOptions } from 'common/Types';
import { Buffer } from 'common/buffer/Buffer';
@@ -196,16 +196,6 @@ export class MockTerminal implements ITerminal {
public deregisterCharacterJoiner(joinerId: number): void { }
}
export class MockInputHandlingTerminal implements IInputHandlingTerminal {
public viewport: IViewport;
public is(term: string): boolean {
throw new Error('Method not implemented.');
}
public resize(x: number, y: number): void {
throw new Error('Method not implemented.');
}
}
export class MockBuffer implements IBuffer {
public markers: IMarker[];
public addMarker(y: number): IMarker {
-9
View File
@@ -15,15 +15,6 @@ export type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;
export type LineData = CharData[];
/**
* This interface encapsulates everything needed from the Terminal by the
* InputHandler. This cleanly separates the large amount of methods needed by
* InputHandler cleanly from the ITerminal interface.
*/
export interface IInputHandlingTerminal {
viewport: IViewport;
}
export interface ICompositionHelper {
compositionstart(): void;
compositionupdate(ev: CompositionEvent): void;