From 8324b43cc25a60d0f6088bfd5d5c20170f9ece77 Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Mon, 22 Aug 2016 17:17:58 +0300 Subject: [PATCH 1/2] Fix Alt + Arrow movement Fix #239 --- src/xterm.js | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/src/xterm.js b/src/xterm.js index b7032b39..bb74a3e2 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -2907,39 +2907,63 @@ break; // left-arrow case 37: - if (modifiers) + if (modifiers) { result.key = '\x1b[1;' + (modifiers + 1) + 'D'; - else if (this.applicationCursor) + // HACK: Make Alt + left-arrow behave like Ctrl + left-arrow: move one word backwards + // http://unix.stackexchange.com/a/108106 + if (result.key == '\x1b[1;3D') { + result.key = '\x1b[1;5D'; + } + } else if (this.applicationCursor) { result.key = '\x1bOD'; - else + } else { result.key = '\x1b[D'; + } break; // right-arrow case 39: - if (modifiers) + if (modifiers) { result.key = '\x1b[1;' + (modifiers + 1) + 'C'; - else if (this.applicationCursor) + // HACK: Make Alt + right-arrow behave like Ctrl + right-arrow: move one word forward + // http://unix.stackexchange.com/a/108106 + if (result.key == '\x1b[1;3C') { + result.key = '\x1b[1;5C'; + } + } else if (this.applicationCursor) { result.key = '\x1bOC'; - else + } else { result.key = '\x1b[C'; + } break; // up-arrow case 38: - if (modifiers) + if (modifiers) { result.key = '\x1b[1;' + (modifiers + 1) + 'A'; - else if (this.applicationCursor) + // HACK: Make Alt + up-arrow behave like Ctrl + up-arrow + // http://unix.stackexchange.com/a/108106 + if (result.key == '\x1b[1;3A') { + result.key = '\x1b[1;5A'; + } + } else if (this.applicationCursor) { result.key = '\x1bOA'; - else + } else { result.key = '\x1b[A'; + } break; // down-arrow case 40: - if (modifiers) + if (modifiers) { result.key = '\x1b[1;' + (modifiers + 1) + 'B'; - else if (this.applicationCursor) + // HACK: Make Alt + down-arrow behave like Ctrl + down-arrow + // http://unix.stackexchange.com/a/108106 + if (result.key == '\x1b[1;3B') { + result.key = '\x1b[1;5B'; + } + } else if (this.applicationCursor) { result.key = '\x1bOB'; - else + } else { result.key = '\x1b[B'; + } break; // insert case 45: From 5d6e0356b3b9f2716b21d895a321aac423c2054f Mon Sep 17 00:00:00 2001 From: Paris Kasidiaris Date: Mon, 22 Aug 2016 17:21:58 +0300 Subject: [PATCH 2/2] Add tests for arrow key movements --- test/test.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/test/test.js b/test/test.js index 33a00035..7b67f234 100644 --- a/test/test.js +++ b/test/test.js @@ -55,6 +55,26 @@ describe('xterm.js', function() { it('should return \\x1b[5C for ctrl+right', function() { assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 39 }).key, '\x1b[1;5C'); // CSI 5 C }); + it('should return \\x1b[5A for ctrl+up', function() { + assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 38 }).key, '\x1b[1;5A'); // CSI 5 A + }); + it('should return \\x1b[5B for ctrl+down', function() { + assert.equal(xterm.evaluateKeyEscapeSequence({ ctrlKey: true, keyCode: 40 }).key, '\x1b[1;5B'); // CSI 5 B + }); + // 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', function() { + assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 37 }).key, '\x1b[1;5D'); // CSI 5 D + }); + it('should return \\x1b[5C for alt+right', function() { + assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 39 }).key, '\x1b[1;5C'); // CSI 5 C + }); + it('should return \\x1b[5A for alt+up', function() { + assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 38 }).key, '\x1b[1;5A'); // CSI 5 A + }); + it('should return \\x1b[5B for alt+down', function() { + assert.equal(xterm.evaluateKeyEscapeSequence({ altKey: true, keyCode: 40 }).key, '\x1b[1;5B'); // CSI 5 B + }); }); describe('attachCustomEventHandler', function () { @@ -88,7 +108,7 @@ describe('xterm.js', function() { }); assert.equal(xterm.keyDown(Object.assign({}, evKeyDown, { keyCode: 77 })), false); }); - + it('should alive after reset(ESC c Full Reset (RIS))', function () { xterm.attachCustomKeydownHandler(function (ev) { return ev.keyCode !== 77;