From 95217ca931397bbdcf8254ae4465583a87dcf8ab Mon Sep 17 00:00:00 2001 From: Daniel Imms Date: Sun, 10 Jun 2018 12:21:06 +0200 Subject: [PATCH] Remove core/input/Keyboard's dep on Terminal --- src/Terminal.test.ts | 257 +----------------------------- src/Terminal.ts | 13 +- src/core/Types.ts | 11 +- src/core/input/Keyboard.test.ts | 273 ++++++++++++++++++++++++++++++++ src/core/input/Keyboard.ts | 49 +++--- 5 files changed, 324 insertions(+), 279 deletions(-) create mode 100644 src/core/input/Keyboard.test.ts diff --git a/src/Terminal.test.ts b/src/Terminal.test.ts index f6cbad52..8974b784 100644 --- a/src/Terminal.test.ts +++ b/src/Terminal.test.ts @@ -13,7 +13,6 @@ const INIT_COLS = 80; const INIT_ROWS = 24; class TestTerminal extends Terminal { - public evaluateKeyEscapeSequence(ev: any): {cancel: boolean, key: string, scrollLines: number} { return this._evaluateKeyEscapeSequence(ev); } public keyDown(ev: any): boolean { return this._keyDown(ev); } public keyPress(ev: any): boolean { return this._keyPress(ev); } } @@ -296,22 +295,19 @@ describe('term.js addons', () => { }); }); - describe('keyDown', () => { + describe('keyPress', () => { it('should scroll down, when a key is pressed and terminal is scrolled up', () => { - // Override _evaluateKeyEscapeSequence to return cancel code - (term)._evaluateKeyEscapeSequence = () => { - return { key: 'a' }; - }; const event = { type: 'keydown', - keyCode: 0, + key: 'a', + keyCode: 65, preventDefault: () => {}, stopPropagation: () => {} }; term.buffer.ydisp = 0; term.buffer.ybase = 40; - term.keyDown(event); + term.keyPress(event); // Ensure that now the terminal is scrolled to bottom assert.equal(term.buffer.ydisp, term.buffer.ybase); @@ -330,7 +326,7 @@ describe('term.js addons', () => { assert.equal(term.buffer.ydisp, startYDisp); term.scrollLines(-1); assert.equal(term.buffer.ydisp, startYDisp - 1); - term.keyDown({ keyCode: 0 }); + term.keyPress({ keyCode: 0 }); assert.equal(term.buffer.ydisp, startYDisp - 1); }); }); @@ -468,249 +464,6 @@ describe('term.js addons', () => { }); }); - describe('evaluateKeyEscapeSequence', () => { - it('should return the correct escape sequence for unmodified keys', () => { - // Backspace - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 8 }).key, '\x7f'); // ^? - // Tab - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 9 }).key, '\t'); - // Return/enter - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 13 }).key, '\r'); // CR - // Escape - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 27 }).key, '\x1b'); - // Page up, page down - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 33 }).key, '\x1b[5~'); // CSI 5 ~ - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 34 }).key, '\x1b[6~'); // CSI 6 ~ - // End, Home - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 35 }).key, '\x1b[F'); // SS3 F - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 36 }).key, '\x1b[H'); // SS3 H - // Left, up, right, down arrows - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 37 }).key, '\x1b[D'); // CSI D - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 38 }).key, '\x1b[A'); // CSI A - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 39 }).key, '\x1b[C'); // CSI C - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 40 }).key, '\x1b[B'); // CSI B - // Insert - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 45 }).key, '\x1b[2~'); // CSI 2 ~ - // Delete - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 46 }).key, '\x1b[3~'); // CSI 3 ~ - // F1-F12 - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 112 }).key, '\x1bOP'); // SS3 P - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 113 }).key, '\x1bOQ'); // SS3 Q - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 114 }).key, '\x1bOR'); // SS3 R - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 115 }).key, '\x1bOS'); // SS3 S - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 116 }).key, '\x1b[15~'); // CSI 1 5 ~ - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 117 }).key, '\x1b[17~'); // CSI 1 7 ~ - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 118 }).key, '\x1b[18~'); // CSI 1 8 ~ - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 119 }).key, '\x1b[19~'); // CSI 1 9 ~ - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 120 }).key, '\x1b[20~'); // CSI 2 0 ~ - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 121 }).key, '\x1b[21~'); // CSI 2 1 ~ - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 122 }).key, '\x1b[23~'); // CSI 2 3 ~ - assert.equal(term.evaluateKeyEscapeSequence({ keyCode: 123 }).key, '\x1b[24~'); // CSI 2 4 ~ - }); - it('should return \\x1b[3;5~ for ctrl+delete', () => { - assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 46 }).key, '\x1b[3;5~'); - }); - it('should return \\x1b[3;2~ for shift+delete', () => { - assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 46 }).key, '\x1b[3;2~'); - }); - it('should return \\x1b[3;3~ for alt+delete', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 46 }).key, '\x1b[3;3~'); - }); - it('should return \\x1b[5D for ctrl+left', () => { - assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 37 }).key, '\x1b[1;5D'); // CSI 5 D - }); - it('should return \\x1b[5C for ctrl+right', () => { - assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 39 }).key, '\x1b[1;5C'); // CSI 5 C - }); - it('should return \\x1b[5A for ctrl+up', () => { - assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 38 }).key, '\x1b[1;5A'); // CSI 5 A - }); - it('should return \\x1b[5B for ctrl+down', () => { - assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 40 }).key, '\x1b[1;5B'); // CSI 5 B - }); - - describe('On non-macOS platforms', () => { - beforeEach(() => { - term.browser.isMac = false; - }); - // Evalueate alt + arrow key movement, which is a feature of terminal emulators but not VT100 - // http://unix.stackexchange.com/a/108106 - it('should return \\x1b[5D for alt+left', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 37 }).key, '\x1b[1;5D'); // CSI 5 D - }); - it('should return \\x1b[5C for alt+right', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 39 }).key, '\x1b[1;5C'); // CSI 5 C - }); - it('should return \\x1ba for alt+a', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 65 }).key, '\x1ba'); - }); - }); - - describe('On macOS platforms', () => { - beforeEach(() => { - term.browser.isMac = true; - }); - it('should return \\x1bb for alt+left', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 37 }).key, '\x1bb'); // CSI 5 D - }); - it('should return \\x1bf for alt+right', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 39 }).key, '\x1bf'); // CSI 5 C - }); - it('should return undefined for alt+a', () => { - assert.strictEqual(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 65 }).key, undefined); - }); - }); - - describe('with macOptionIsMeta', () => { - beforeEach(() => { - term.browser.isMac = true; - term.setOption('macOptionIsMeta', true); - }); - it('should return \\x1ba for alt+a', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 65 }).key, '\x1ba'); - }); - }); - - it('should return \\x1b[5A for alt+up', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 38 }).key, '\x1b[1;5A'); // CSI 5 A - }); - it('should return \\x1b[5B for alt+down', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 40 }).key, '\x1b[1;5B'); // CSI 5 B - }); - it('should return the correct escape sequence for modified F1-F12 keys', () => { - assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 112 }).key, '\x1b[1;2P'); - assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 113 }).key, '\x1b[1;2Q'); - assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 114 }).key, '\x1b[1;2R'); - assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 115 }).key, '\x1b[1;2S'); - assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 116 }).key, '\x1b[15;2~'); - assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 117 }).key, '\x1b[17;2~'); - assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 118 }).key, '\x1b[18;2~'); - assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 119 }).key, '\x1b[19;2~'); - assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 120 }).key, '\x1b[20;2~'); - assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 121 }).key, '\x1b[21;2~'); - assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 122 }).key, '\x1b[23;2~'); - assert.equal(term.evaluateKeyEscapeSequence({ shiftKey: true, keyCode: 123 }).key, '\x1b[24;2~'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 112 }).key, '\x1b[1;3P'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 113 }).key, '\x1b[1;3Q'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 114 }).key, '\x1b[1;3R'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 115 }).key, '\x1b[1;3S'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 116 }).key, '\x1b[15;3~'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 117 }).key, '\x1b[17;3~'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 118 }).key, '\x1b[18;3~'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 119 }).key, '\x1b[19;3~'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 120 }).key, '\x1b[20;3~'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 121 }).key, '\x1b[21;3~'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 122 }).key, '\x1b[23;3~'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, keyCode: 123 }).key, '\x1b[24;3~'); - - assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 112 }).key, '\x1b[1;5P'); - assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 113 }).key, '\x1b[1;5Q'); - assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 114 }).key, '\x1b[1;5R'); - assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 115 }).key, '\x1b[1;5S'); - assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 116 }).key, '\x1b[15;5~'); - assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 117 }).key, '\x1b[17;5~'); - assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 118 }).key, '\x1b[18;5~'); - assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 119 }).key, '\x1b[19;5~'); - assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 120 }).key, '\x1b[20;5~'); - assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 121 }).key, '\x1b[21;5~'); - assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 122 }).key, '\x1b[23;5~'); - assert.equal(term.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 123 }).key, '\x1b[24;5~'); - }); - - // Characters using ctrl+alt sequences - it('should return proper sequence for ctrl+alt+a', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, ctrlKey: true, keyCode: 65 }).key, '\x1b\x01'); - }); - - // Characters using alt sequences (numbers) - it('should return proper sequences for alt+0', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 48 }).key, '\x1b0'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 48 }).key, '\x1b)'); - }); - it('should return proper sequences for alt+1', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 49 }).key, '\x1b1'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 49 }).key, '\x1b!'); - }); - it('should return proper sequences for alt+2', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 50 }).key, '\x1b2'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 50 }).key, '\x1b@'); - }); - it('should return proper sequences for alt+3', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 51 }).key, '\x1b3'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 51 }).key, '\x1b#'); - }); - it('should return proper sequences for alt+4', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 52 }).key, '\x1b4'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 52 }).key, '\x1b$'); - }); - it('should return proper sequences for alt+5', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 53 }).key, '\x1b5'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 53 }).key, '\x1b%'); - }); - it('should return proper sequences for alt+6', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 54 }).key, '\x1b6'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 54 }).key, '\x1b^'); - }); - it('should return proper sequences for alt+7', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 55 }).key, '\x1b7'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 55 }).key, '\x1b&'); - }); - it('should return proper sequences for alt+8', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 56 }).key, '\x1b8'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 56 }).key, '\x1b*'); - }); - it('should return proper sequences for alt+9', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 57 }).key, '\x1b9'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 57 }).key, '\x1b('); - }); - - // Characters using alt sequences (special chars) - it('should return proper sequences for alt+;', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 186 }).key, '\x1b;'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 186 }).key, '\x1b:'); - }); - it('should return proper sequences for alt+=', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 187 }).key, '\x1b='); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 187 }).key, '\x1b+'); - }); - it('should return proper sequences for alt+,', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 188 }).key, '\x1b,'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 188 }).key, '\x1b<'); - }); - it('should return proper sequences for alt+-', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 189 }).key, '\x1b-'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 189 }).key, '\x1b_'); - }); - it('should return proper sequences for alt+.', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 190 }).key, '\x1b.'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 190 }).key, '\x1b>'); - }); - it('should return proper sequences for alt+/', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 191 }).key, '\x1b/'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 191 }).key, '\x1b?'); - }); - it('should return proper sequences for alt+~', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 192 }).key, '\x1b`'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 192 }).key, '\x1b~'); - }); - it('should return proper sequences for alt+[', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 219 }).key, '\x1b['); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 219 }).key, '\x1b{'); - }); - it('should return proper sequences for alt+\\', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 220 }).key, '\x1b\\'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 220 }).key, '\x1b|'); - }); - it('should return proper sequences for alt+]', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 221 }).key, '\x1b]'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 221 }).key, '\x1b}'); - }); - it('should return proper sequences for alt+\'', () => { - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 222 }).key, '\x1b\''); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, keyCode: 222 }).key, '\x1b"'); - }); - }); - describe('Third level shift', () => { let evKeyDown: any; let evKeyPress: any; diff --git a/src/Terminal.ts b/src/Terminal.ts index 1b7a0c1a..a1918353 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -52,6 +52,7 @@ import { removeTerminalFromCache } from './renderer/atlas/CharAtlasCache'; import { DomRenderer } from './renderer/dom/DomRenderer'; import { IKeyboardEvent } from './base/Types'; import { evaluateKeyboardEvent } from './core/input/Keyboard'; +import { KeyboardResultType } from './core/Types'; // Let it work inside Node.js for automated testing purposes. const document = (typeof window !== 'undefined') ? window.document : null; @@ -1422,7 +1423,7 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II return false; } - const result = evaluateKeyboardEvent(event); + const result = evaluateKeyboardEvent(event, this.applicationCursor, this.browser.isMac, this.options.macOptionIsMeta); // if (result.key === C0.DC3) { // XOFF // this._writeStopped = true; @@ -1430,11 +1431,17 @@ export class Terminal extends EventEmitter implements ITerminal, IDisposable, II // this._writeStopped = false; // } - if (result.scrollLines) { - this.scrollLines(result.scrollLines); + if (result.type === KeyboardResultType.PAGE_DOWN || result.type === KeyboardResultType.PAGE_UP) { + const scrollCount = this.rows - 1; + this.scrollLines(result.type === KeyboardResultType.PAGE_UP ? -scrollCount : scrollCount); return this.cancel(event, true); } + if (result.type === KeyboardResultType.SELECT_ALL) { + this.selectAll(); + // TODO: Verify cancel behavior is the same as before + } + if (this._isThirdLevelShift(this.browser, event)) { return true; } diff --git a/src/core/Types.ts b/src/core/Types.ts index 374b8f7d..cc5c0d1b 100644 --- a/src/core/Types.ts +++ b/src/core/Types.ts @@ -3,8 +3,15 @@ * @license MIT */ +export const enum KeyboardResultType { + SEND_KEY, + SELECT_ALL, + PAGE_UP, + PAGE_DOWN +} + export interface IKeyboardResult { + type: KeyboardResultType; cancel: boolean; - key: string; - scrollLines: number; + key: string | undefined; } diff --git a/src/core/input/Keyboard.test.ts b/src/core/input/Keyboard.test.ts new file mode 100644 index 00000000..97a12c88 --- /dev/null +++ b/src/core/input/Keyboard.test.ts @@ -0,0 +1,273 @@ + +import { assert } from 'chai'; +import { evaluateKeyboardEvent } from './Keyboard'; +import { IKeyboardResult } from '../Types'; + +/** + * A helper function for testing which allows passing in a partial event and defaults will be filled + * in on it. + */ +function testEvaluateKeyboardEvent(partialEvent: { + altKey?: boolean; + ctrlKey?: boolean; + shiftKey?: boolean; + metaKey?: boolean; + keyCode?: number; + key?: string; + type?: string; +}, partialOptions: { + applicationCursorMode?: boolean; + isMac?: boolean; + macOptionIsMeta?: boolean; +} = {}): IKeyboardResult { + const event = { + altKey: partialEvent.altKey || false, + ctrlKey: partialEvent.ctrlKey || false, + shiftKey: partialEvent.shiftKey || false, + metaKey: partialEvent.metaKey || false, + keyCode: partialEvent.keyCode || undefined, + key: partialEvent.key || '', + type: partialEvent.type || '' + }; + const options = { + applicationCursorMode: partialOptions.applicationCursorMode || false, + isMac: partialOptions.isMac || false, + macOptionIsMeta: partialOptions.macOptionIsMeta || false + }; + return evaluateKeyboardEvent(event, options.applicationCursorMode, options.isMac, options.macOptionIsMeta); +} + +describe('Keyboard', () => { + describe('evaluateKeyEscapeSequence', () => { + it('should return the correct escape sequence for unmodified keys', () => { + // Backspace + assert.equal(testEvaluateKeyboardEvent({ keyCode: 8 }).key, '\x7f'); // ^? + // Tab + assert.equal(testEvaluateKeyboardEvent({ keyCode: 9 }).key, '\t'); + // Return/enter + assert.equal(testEvaluateKeyboardEvent({ keyCode: 13 }).key, '\r'); // CR + // Escape + assert.equal(testEvaluateKeyboardEvent({ keyCode: 27 }).key, '\x1b'); + // Page up, page down + assert.equal(testEvaluateKeyboardEvent({ keyCode: 33 }).key, '\x1b[5~'); // CSI 5 ~ + assert.equal(testEvaluateKeyboardEvent({ keyCode: 34 }).key, '\x1b[6~'); // CSI 6 ~ + // End, Home + assert.equal(testEvaluateKeyboardEvent({ keyCode: 35 }).key, '\x1b[F'); // SS3 F + assert.equal(testEvaluateKeyboardEvent({ keyCode: 36 }).key, '\x1b[H'); // SS3 H + // Left, up, right, down arrows + assert.equal(testEvaluateKeyboardEvent({ keyCode: 37 }).key, '\x1b[D'); // CSI D + assert.equal(testEvaluateKeyboardEvent({ keyCode: 38 }).key, '\x1b[A'); // CSI A + assert.equal(testEvaluateKeyboardEvent({ keyCode: 39 }).key, '\x1b[C'); // CSI C + assert.equal(testEvaluateKeyboardEvent({ keyCode: 40 }).key, '\x1b[B'); // CSI B + // Insert + assert.equal(testEvaluateKeyboardEvent({ keyCode: 45 }).key, '\x1b[2~'); // CSI 2 ~ + // Delete + assert.equal(testEvaluateKeyboardEvent({ keyCode: 46 }).key, '\x1b[3~'); // CSI 3 ~ + // F1-F12 + assert.equal(testEvaluateKeyboardEvent({ keyCode: 112 }).key, '\x1bOP'); // SS3 P + assert.equal(testEvaluateKeyboardEvent({ keyCode: 113 }).key, '\x1bOQ'); // SS3 Q + assert.equal(testEvaluateKeyboardEvent({ keyCode: 114 }).key, '\x1bOR'); // SS3 R + assert.equal(testEvaluateKeyboardEvent({ keyCode: 115 }).key, '\x1bOS'); // SS3 S + assert.equal(testEvaluateKeyboardEvent({ keyCode: 116 }).key, '\x1b[15~'); // CSI 1 5 ~ + assert.equal(testEvaluateKeyboardEvent({ keyCode: 117 }).key, '\x1b[17~'); // CSI 1 7 ~ + assert.equal(testEvaluateKeyboardEvent({ keyCode: 118 }).key, '\x1b[18~'); // CSI 1 8 ~ + assert.equal(testEvaluateKeyboardEvent({ keyCode: 119 }).key, '\x1b[19~'); // CSI 1 9 ~ + assert.equal(testEvaluateKeyboardEvent({ keyCode: 120 }).key, '\x1b[20~'); // CSI 2 0 ~ + assert.equal(testEvaluateKeyboardEvent({ keyCode: 121 }).key, '\x1b[21~'); // CSI 2 1 ~ + assert.equal(testEvaluateKeyboardEvent({ keyCode: 122 }).key, '\x1b[23~'); // CSI 2 3 ~ + assert.equal(testEvaluateKeyboardEvent({ keyCode: 123 }).key, '\x1b[24~'); // CSI 2 4 ~ + }); + it('should return \\x1b[3;5~ for ctrl+delete', () => { + assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 46 }).key, '\x1b[3;5~'); + }); + it('should return \\x1b[3;2~ for shift+delete', () => { + assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 46 }).key, '\x1b[3;2~'); + }); + it('should return \\x1b[3;3~ for alt+delete', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 46 }).key, '\x1b[3;3~'); + }); + it('should return \\x1b[5D for ctrl+left', () => { + assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 37 }).key, '\x1b[1;5D'); // CSI 5 D + }); + it('should return \\x1b[5C for ctrl+right', () => { + assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 39 }).key, '\x1b[1;5C'); // CSI 5 C + }); + it('should return \\x1b[5A for ctrl+up', () => { + assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 38 }).key, '\x1b[1;5A'); // CSI 5 A + }); + it('should return \\x1b[5B for ctrl+down', () => { + assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 40 }).key, '\x1b[1;5B'); // CSI 5 B + }); + + describe('On non-macOS platforms', () => { + // Evalueate alt + arrow key movement, which is a feature of terminal emulators but not VT100 + // http://unix.stackexchange.com/a/108106 + it('should return \\x1b[5D for alt+left', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 37 }, { isMac: false }).key, '\x1b[1;5D'); // CSI 5 D + }); + it('should return \\x1b[5C for alt+right', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 39 }, { isMac: false }).key, '\x1b[1;5C'); // CSI 5 C + }); + it('should return \\x1ba for alt+a', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 65 }, { isMac: false }).key, '\x1ba'); + }); + }); + + describe('On macOS platforms', () => { + it('should return \\x1bb for alt+left', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 37 }, { isMac: true }).key, '\x1bb'); // CSI 5 D + }); + it('should return \\x1bf for alt+right', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 39 }, { isMac: true }).key, '\x1bf'); // CSI 5 C + }); + it('should return undefined for alt+a', () => { + assert.strictEqual(testEvaluateKeyboardEvent({ altKey: true, keyCode: 65 }, { isMac: true }).key, undefined), { isMac: true }; + }); + }); + + describe('with macOptionIsMeta', () => { + it('should return \\x1ba for alt+a', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 65 }, { isMac: true, macOptionIsMeta: true }).key, '\x1ba'); + }); + }); + + it('should return \\x1b[5A for alt+up', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 38 }).key, '\x1b[1;5A'); // CSI 5 A + }); + it('should return \\x1b[5B for alt+down', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 40 }).key, '\x1b[1;5B'); // CSI 5 B + }); + it('should return the correct escape sequence for modified F1-F12 keys', () => { + assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 112 }).key, '\x1b[1;2P'); + assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 113 }).key, '\x1b[1;2Q'); + assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 114 }).key, '\x1b[1;2R'); + assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 115 }).key, '\x1b[1;2S'); + assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 116 }).key, '\x1b[15;2~'); + assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 117 }).key, '\x1b[17;2~'); + assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 118 }).key, '\x1b[18;2~'); + assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 119 }).key, '\x1b[19;2~'); + assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 120 }).key, '\x1b[20;2~'); + assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 121 }).key, '\x1b[21;2~'); + assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 122 }).key, '\x1b[23;2~'); + assert.equal(testEvaluateKeyboardEvent({ shiftKey: true, keyCode: 123 }).key, '\x1b[24;2~'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 112 }).key, '\x1b[1;3P'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 113 }).key, '\x1b[1;3Q'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 114 }).key, '\x1b[1;3R'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 115 }).key, '\x1b[1;3S'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 116 }).key, '\x1b[15;3~'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 117 }).key, '\x1b[17;3~'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 118 }).key, '\x1b[18;3~'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 119 }).key, '\x1b[19;3~'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 120 }).key, '\x1b[20;3~'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 121 }).key, '\x1b[21;3~'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 122 }).key, '\x1b[23;3~'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, keyCode: 123 }).key, '\x1b[24;3~'); + + assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 112 }).key, '\x1b[1;5P'); + assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 113 }).key, '\x1b[1;5Q'); + assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 114 }).key, '\x1b[1;5R'); + assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 115 }).key, '\x1b[1;5S'); + assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 116 }).key, '\x1b[15;5~'); + assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 117 }).key, '\x1b[17;5~'); + assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 118 }).key, '\x1b[18;5~'); + assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 119 }).key, '\x1b[19;5~'); + assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 120 }).key, '\x1b[20;5~'); + assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 121 }).key, '\x1b[21;5~'); + assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 122 }).key, '\x1b[23;5~'); + assert.equal(testEvaluateKeyboardEvent({ ctrlKey: true, keyCode: 123 }).key, '\x1b[24;5~'); + }); + + // Characters using ctrl+alt sequences + it('should return proper sequence for ctrl+alt+a', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, ctrlKey: true, keyCode: 65 }).key, '\x1b\x01'); + }); + + // Characters using alt sequences (numbers) + it('should return proper sequences for alt+0', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 48 }).key, '\x1b0'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 48 }).key, '\x1b)'); + }); + it('should return proper sequences for alt+1', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 49 }).key, '\x1b1'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 49 }).key, '\x1b!'); + }); + it('should return proper sequences for alt+2', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 50 }).key, '\x1b2'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 50 }).key, '\x1b@'); + }); + it('should return proper sequences for alt+3', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 51 }).key, '\x1b3'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 51 }).key, '\x1b#'); + }); + it('should return proper sequences for alt+4', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 52 }).key, '\x1b4'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 52 }).key, '\x1b$'); + }); + it('should return proper sequences for alt+5', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 53 }).key, '\x1b5'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 53 }).key, '\x1b%'); + }); + it('should return proper sequences for alt+6', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 54 }).key, '\x1b6'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 54 }).key, '\x1b^'); + }); + it('should return proper sequences for alt+7', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 55 }).key, '\x1b7'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 55 }).key, '\x1b&'); + }); + it('should return proper sequences for alt+8', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 56 }).key, '\x1b8'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 56 }).key, '\x1b*'); + }); + it('should return proper sequences for alt+9', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 57 }).key, '\x1b9'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 57 }).key, '\x1b('); + }); + + // Characters using alt sequences (special chars) + it('should return proper sequences for alt+;', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 186 }).key, '\x1b;'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 186 }).key, '\x1b:'); + }); + it('should return proper sequences for alt+=', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 187 }).key, '\x1b='); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 187 }).key, '\x1b+'); + }); + it('should return proper sequences for alt+,', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 188 }).key, '\x1b,'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 188 }).key, '\x1b<'); + }); + it('should return proper sequences for alt+-', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 189 }).key, '\x1b-'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 189 }).key, '\x1b_'); + }); + it('should return proper sequences for alt+.', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 190 }).key, '\x1b.'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 190 }).key, '\x1b>'); + }); + it('should return proper sequences for alt+/', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 191 }).key, '\x1b/'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 191 }).key, '\x1b?'); + }); + it('should return proper sequences for alt+~', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 192 }).key, '\x1b`'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 192 }).key, '\x1b~'); + }); + it('should return proper sequences for alt+[', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 219 }).key, '\x1b['); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 219 }).key, '\x1b{'); + }); + it('should return proper sequences for alt+\\', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 220 }).key, '\x1b\\'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 220 }).key, '\x1b|'); + }); + it('should return proper sequences for alt+]', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 221 }).key, '\x1b]'); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 221 }).key, '\x1b}'); + }); + it('should return proper sequences for alt+\'', () => { + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: false, keyCode: 222 }).key, '\x1b\''); + assert.equal(testEvaluateKeyboardEvent({ altKey: true, shiftKey: true, keyCode: 222 }).key, '\x1b"'); + }); + }); +}); diff --git a/src/core/input/Keyboard.ts b/src/core/input/Keyboard.ts index caaa9189..f4393276 100644 --- a/src/core/input/Keyboard.ts +++ b/src/core/input/Keyboard.ts @@ -5,7 +5,7 @@ */ import { IKeyboardEvent } from '../../base/Types'; -import { IKeyboardResult } from '../Types'; +import { IKeyboardResult, KeyboardResultType } from '../Types'; import { C0 } from '../../EscapeSequences'; // reg + shift key mappings for digits and special chars @@ -36,42 +36,46 @@ const KEYCODE_KEY_MAPPINGS: { [key: number]: [string, string]} = { 222: ['\'', '"'] }; -export function evaluateKeyboardEvent(ev: IKeyboardEvent): IKeyboardResult { +export function evaluateKeyboardEvent( + ev: IKeyboardEvent, + applicationCursorMode: boolean, + isMac: boolean, + macOptionIsMeta: boolean +): IKeyboardResult { const result: IKeyboardResult = { + type: KeyboardResultType.SEND_KEY, // Whether to cancel event propogation (NOTE: this may not be needed since the event is // canceled at the end of keyDown cancel: false, // The new key even to emit - key: undefined, - // The number of characters to scroll, if this is defined it will cancel the event - scrollLines: undefined + key: undefined }; const modifiers = (ev.shiftKey ? 1 : 0) | (ev.altKey ? 2 : 0) | (ev.ctrlKey ? 4 : 0) | (ev.metaKey ? 8 : 0); switch (ev.keyCode) { case 0: if (ev.key === 'UIKeyInputUpArrow') { - if (this.applicationCursor) { + if (applicationCursorMode) { result.key = C0.ESC + 'OA'; } else { result.key = C0.ESC + '[A'; } } else if (ev.key === 'UIKeyInputLeftArrow') { - if (this.applicationCursor) { + if (applicationCursorMode) { result.key = C0.ESC + 'OD'; } else { result.key = C0.ESC + '[D'; } } else if (ev.key === 'UIKeyInputRightArrow') { - if (this.applicationCursor) { + if (applicationCursorMode) { result.key = C0.ESC + 'OC'; } else { result.key = C0.ESC + '[C'; } } else if (ev.key === 'UIKeyInputDownArrow') { - if (this.applicationCursor) { + if (applicationCursorMode) { result.key = C0.ESC + 'OB'; } else { result.key = C0.ESC + '[B'; @@ -116,9 +120,9 @@ export function evaluateKeyboardEvent(ev: IKeyboardEvent): IKeyboardResult { // http://unix.stackexchange.com/a/108106 // macOS uses different escape sequences than linux if (result.key === C0.ESC + '[1;3D') { - result.key = (this.browser.isMac) ? C0.ESC + 'b' : C0.ESC + '[1;5D'; + result.key = isMac ? C0.ESC + 'b' : C0.ESC + '[1;5D'; } - } else if (this.applicationCursor) { + } else if (applicationCursorMode) { result.key = C0.ESC + 'OD'; } else { result.key = C0.ESC + '[D'; @@ -132,9 +136,9 @@ export function evaluateKeyboardEvent(ev: IKeyboardEvent): IKeyboardResult { // http://unix.stackexchange.com/a/108106 // macOS uses different escape sequences than linux if (result.key === C0.ESC + '[1;3C') { - result.key = (this.browser.isMac) ? C0.ESC + 'f' : C0.ESC + '[1;5C'; + result.key = isMac ? C0.ESC + 'f' : C0.ESC + '[1;5C'; } - } else if (this.applicationCursor) { + } else if (applicationCursorMode) { result.key = C0.ESC + 'OC'; } else { result.key = C0.ESC + '[C'; @@ -149,7 +153,7 @@ export function evaluateKeyboardEvent(ev: IKeyboardEvent): IKeyboardResult { if (result.key === C0.ESC + '[1;3A') { result.key = C0.ESC + '[1;5A'; } - } else if (this.applicationCursor) { + } else if (applicationCursorMode) { result.key = C0.ESC + 'OA'; } else { result.key = C0.ESC + '[A'; @@ -164,7 +168,7 @@ export function evaluateKeyboardEvent(ev: IKeyboardEvent): IKeyboardResult { if (result.key === C0.ESC + '[1;3B') { result.key = C0.ESC + '[1;5B'; } - } else if (this.applicationCursor) { + } else if (applicationCursorMode) { result.key = C0.ESC + 'OB'; } else { result.key = C0.ESC + '[B'; @@ -190,7 +194,7 @@ export function evaluateKeyboardEvent(ev: IKeyboardEvent): IKeyboardResult { // home if (modifiers) { result.key = C0.ESC + '[1;' + (modifiers + 1) + 'H'; - } else if (this.applicationCursor) { + } else if (applicationCursorMode) { result.key = C0.ESC + 'OH'; } else { result.key = C0.ESC + '[H'; @@ -200,7 +204,7 @@ export function evaluateKeyboardEvent(ev: IKeyboardEvent): IKeyboardResult { // end if (modifiers) { result.key = C0.ESC + '[1;' + (modifiers + 1) + 'F'; - } else if (this.applicationCursor) { + } else if (applicationCursorMode) { result.key = C0.ESC + 'OF'; } else { result.key = C0.ESC + '[F'; @@ -209,7 +213,7 @@ export function evaluateKeyboardEvent(ev: IKeyboardEvent): IKeyboardResult { case 33: // page up if (ev.shiftKey) { - result.scrollLines = -(this.rows - 1); + result.type = KeyboardResultType.PAGE_UP; } else { result.key = C0.ESC + '[5~'; } @@ -217,7 +221,7 @@ export function evaluateKeyboardEvent(ev: IKeyboardEvent): IKeyboardResult { case 34: // page down if (ev.shiftKey) { - result.scrollLines = this.rows - 1; + result.type = KeyboardResultType.PAGE_DOWN; } else { result.key = C0.ESC + '[6~'; } @@ -331,7 +335,7 @@ export function evaluateKeyboardEvent(ev: IKeyboardEvent): IKeyboardResult { // ^] - Operating System Command (OSC) result.key = String.fromCharCode(29); } - } else if ((!this.browser.isMac || this.options.macOptionIsMeta) && ev.altKey && !ev.metaKey) { + } else if ((!isMac || macOptionIsMeta) && ev.altKey && !ev.metaKey) { // On macOS this is a third level shift when !macOptionIsMeta. Use instead. const keyMapping = KEYCODE_KEY_MAPPINGS[ev.keyCode]; const key = keyMapping && keyMapping[!ev.shiftKey ? 0 : 1]; @@ -341,9 +345,10 @@ export function evaluateKeyboardEvent(ev: IKeyboardEvent): IKeyboardResult { const keyCode = ev.ctrlKey ? ev.keyCode - 64 : ev.keyCode + 32; result.key = C0.ESC + String.fromCharCode(keyCode); } - } else if (this.browser.isMac && !ev.altKey && !ev.ctrlKey && ev.metaKey) { + } else if (isMac && !ev.altKey && !ev.ctrlKey && ev.metaKey) { if (ev.keyCode === 65) { // cmd + a - this.selectAll(); + result.type = KeyboardResultType.SELECT_ALL; + // TODO: Select all in terminal side } } break;