diff --git a/src/Terminal.test.ts b/src/Terminal.test.ts index 746cdeba..301ab020 100644 --- a/src/Terminal.test.ts +++ b/src/Terminal.test.ts @@ -584,7 +584,49 @@ describe('term.js addons', () => { assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, ctrlKey: true, keyCode: 65 }).key, '\x1b\x01'); }); - // Characters using alt sequences + // 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:'); @@ -605,10 +647,13 @@ describe('term.js addons', () => { 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+~', () => { - // tilde is a DEAD key assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: false, keyCode: 192 }).key, '\x1b`'); - assert.equal(term.evaluateKeyEscapeSequence({ altKey: true, shiftKey: true, 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['); diff --git a/src/Terminal.ts b/src/Terminal.ts index f737adbb..ddb647da 100644 --- a/src/Terminal.ts +++ b/src/Terminal.ts @@ -46,6 +46,33 @@ import { DEFAULT_ANSI_COLORS } from './renderer/ColorManager'; import { MouseZoneManager } from './input/MouseZoneManager'; import { ITheme } from 'xterm'; +// reg + shift key mappings for digits and special chars +const KEYCODE_KEY_MAPPINGS = { + // digits 0-9 + 48: ['0', ')'], + 49: ['1', '!'], + 50: ['2', '@'], + 51: ['3', '#'], + 52: ['4', '$'], + 53: ['5', '%'], + 54: ['6', '^'], + 55: ['7', '&'], + 56: ['8', '*'], + 57: ['9', '('], + + // special chars + 186: [';', ':'], + 187: ['=', '+'], + 188: [',', '<'], + 189: ['-', '_'], + 190: ['.', '>'], + 191: ['/', '?'], + 192: ['`', '~'], + 219: ['[', '{'], + 221: [']', '}'], + 222: ['\'', '|'] +}; + // Let it work inside Node.js for automated testing purposes. const document = (typeof window !== 'undefined') ? window.document : null; @@ -1727,44 +1754,13 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT } } else if ((!this.browser.isMac || this.options.macOptionIsMeta) && ev.altKey && !ev.metaKey) { // On macOS this is a third level shift when !macOptionIsMeta. Use instead. - if (ev.keyCode >= 65 && ev.keyCode <= 90) { + const keyMapping = KEYCODE_KEY_MAPPINGS[ev.keyCode]; + const key = keyMapping && keyMapping[!ev.shiftKey ? 0 : 1]; + if (key) { + result.key = C0.ESC + key; + } else if (ev.keyCode >= 65 && ev.keyCode <= 90) { const keyCode = ev.ctrlKey ? ev.keyCode - 64 : ev.keyCode + 32; result.key = C0.ESC + String.fromCharCode(keyCode); - } else if (ev.keyCode >= 48 && ev.keyCode <= 57) { - result.key = C0.ESC + (ev.keyCode - 48); - } else { - const t = (p, s) => !ev.shiftKey ? p : s; - switch (ev.keyCode) { - case 186: - result.key = C0.ESC + t(';', ':'); - break; - case 187: - result.key = C0.ESC + t('=', '+'); - break; - case 188: - result.key = C0.ESC + t(',', '<'); - break; - case 189: - result.key = C0.ESC + t('-', '_'); - break; - case 190: - result.key = C0.ESC + t('.', '>'); - break; - case 192: - // the tilde is a DEAD key - result.key = C0.ESC + '`'; - break; - case 219: - result.key = C0.ESC + t('[', '{'); - break; - case 221: - result.key = C0.ESC + t(']', '}'); - break; - case 222: - result.key = C0.ESC + t('\'', '|'); - break; - - } } } else if (this.browser.isMac && !ev.altKey && !ev.ctrlKey && ev.metaKey) { if (ev.keyCode === 65) { // cmd + a