Skip to content

Commit 4f4faa8

Browse files
elie-gruyadorno
authored andcommitted
readline: fix key name for function keys with modifiers
Fixes: #35251 PR-URL: #35268 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
1 parent b860a7f commit 4f4faa8

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

lib/internal/readline/utils.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,13 @@ function* emitKeys(stream) {
199199

200200
// Parse the key itself
201201
switch (code) {
202-
/* xterm/gnome ESC O letter */
202+
/* xterm/gnome ESC [ letter (with modifier) */
203+
case '[P': key.name = 'f1'; break;
204+
case '[Q': key.name = 'f2'; break;
205+
case '[R': key.name = 'f3'; break;
206+
case '[S': key.name = 'f4'; break;
207+
208+
/* xterm/gnome ESC O letter (without modifier) */
203209
case 'OP': key.name = 'f1'; break;
204210
case 'OQ': key.name = 'f2'; break;
205211
case 'OR': key.name = 'f3'; break;
@@ -296,12 +302,15 @@ function* emitKeys(stream) {
296302
} else if (ch === '\r') {
297303
// carriage return
298304
key.name = 'return';
305+
key.meta = escaped;
299306
} else if (ch === '\n') {
300307
// Enter, should have been called linefeed
301308
key.name = 'enter';
309+
key.meta = escaped;
302310
} else if (ch === '\t') {
303311
// tab
304312
key.name = 'tab';
313+
key.meta = escaped;
305314
} else if (ch === '\b' || ch === '\x7f') {
306315
// backspace or ctrl+h
307316
key.name = 'backspace';

test/parallel/test-readline-keys.js

+23-1
Original file line numberDiff line numberDiff line change
@@ -92,10 +92,13 @@ addTest('io.JS', [
9292
]);
9393

9494
// Named characters
95-
addTest('\n\r\t', [
95+
addTest('\n\r\t\x1b\n\x1b\r\x1b\t', [
9696
{ name: 'enter', sequence: '\n' },
9797
{ name: 'return', sequence: '\r' },
9898
{ name: 'tab', sequence: '\t' },
99+
{ name: 'enter', sequence: '\x1b\n', meta: true },
100+
{ name: 'return', sequence: '\x1b\r', meta: true },
101+
{ name: 'tab', sequence: '\x1b\t', meta: true },
99102
]);
100103

101104
// Space and backspace
@@ -132,6 +135,25 @@ addTest('a\x1baA\x1bA', [
132135
{ name: 'a', sequence: '\x1bA', meta: true, shift: true },
133136
]);
134137

138+
// xterm/gnome ESC [ letter (with modifiers)
139+
/* eslint-disable max-len */
140+
addTest('\x1b[2P\x1b[3P\x1b[4P\x1b[5P\x1b[6P\x1b[7P\x1b[8P\x1b[3Q\x1b[8Q\x1b[3R\x1b[8R\x1b[3S\x1b[8S', [
141+
{ name: 'f1', sequence: '\x1b[2P', code: '[P', shift: true, meta: false, ctrl: false },
142+
{ name: 'f1', sequence: '\x1b[3P', code: '[P', shift: false, meta: true, ctrl: false },
143+
{ name: 'f1', sequence: '\x1b[4P', code: '[P', shift: true, meta: true, ctrl: false },
144+
{ name: 'f1', sequence: '\x1b[5P', code: '[P', shift: false, meta: false, ctrl: true },
145+
{ name: 'f1', sequence: '\x1b[6P', code: '[P', shift: true, meta: false, ctrl: true },
146+
{ name: 'f1', sequence: '\x1b[7P', code: '[P', shift: false, meta: true, ctrl: true },
147+
{ name: 'f1', sequence: '\x1b[8P', code: '[P', shift: true, meta: true, ctrl: true },
148+
{ name: 'f2', sequence: '\x1b[3Q', code: '[Q', meta: true },
149+
{ name: 'f2', sequence: '\x1b[8Q', code: '[Q', shift: true, meta: true, ctrl: true },
150+
{ name: 'f3', sequence: '\x1b[3R', code: '[R', meta: true },
151+
{ name: 'f3', sequence: '\x1b[8R', code: '[R', shift: true, meta: true, ctrl: true },
152+
{ name: 'f4', sequence: '\x1b[3S', code: '[S', meta: true },
153+
{ name: 'f4', sequence: '\x1b[8S', code: '[S', shift: true, meta: true, ctrl: true },
154+
]);
155+
/* eslint-enable max-len */
156+
135157
// xterm/gnome ESC O letter
136158
addTest('\x1bOP\x1bOQ\x1bOR\x1bOS', [
137159
{ name: 'f1', sequence: '\x1bOP', code: 'OP' },

0 commit comments

Comments
 (0)