Skip to content

Commit e0c69b3

Browse files
ServeurpersoComngxson
authored andcommitted
console: fix arrow keys on Windows using private-use Unicode
1 parent 77ca259 commit e0c69b3

File tree

1 file changed

+37
-0
lines changed

1 file changed

+37
-0
lines changed

common/console.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@
3636

3737
namespace console {
3838

39+
namespace {
40+
// Use private-use unicode values to represent special keys that are not reported
41+
// as characters (e.g. arrows on Windows). These values should never clash with
42+
// real input and let the rest of the code handle navigation uniformly.
43+
static constexpr char32_t KEY_ARROW_LEFT = 0xE000;
44+
static constexpr char32_t KEY_ARROW_RIGHT = 0xE001;
45+
static constexpr char32_t KEY_ARROW_UP = 0xE002;
46+
static constexpr char32_t KEY_ARROW_DOWN = 0xE003;
47+
}
48+
3949
//
4050
// Console state
4151
//
@@ -176,6 +186,15 @@ namespace console {
176186

177187
if (record.EventType == KEY_EVENT && record.Event.KeyEvent.bKeyDown) {
178188
wchar_t wc = record.Event.KeyEvent.uChar.UnicodeChar;
189+
if (wc == 0) {
190+
switch (record.Event.KeyEvent.wVirtualKeyCode) {
191+
case VK_LEFT: return KEY_ARROW_LEFT;
192+
case VK_RIGHT: return KEY_ARROW_RIGHT;
193+
case VK_UP: return KEY_ARROW_UP;
194+
case VK_DOWN: return KEY_ARROW_DOWN;
195+
default: continue;
196+
}
197+
}
179198
if (wc == 0) {
180199
continue;
181200
}
@@ -462,6 +481,24 @@ namespace console {
462481
}
463482
}
464483
}
484+
#if defined(_WIN32)
485+
} else if (input_char == KEY_ARROW_LEFT) {
486+
if (char_pos > 0) {
487+
int w = widths[char_pos - 1];
488+
move_cursor(-w);
489+
char_pos--;
490+
byte_pos = prev_utf8_char_pos(line, byte_pos);
491+
}
492+
} else if (input_char == KEY_ARROW_RIGHT) {
493+
if (char_pos < widths.size()) {
494+
int w = widths[char_pos];
495+
move_cursor(w);
496+
char_pos++;
497+
byte_pos = next_utf8_char_pos(line, byte_pos);
498+
}
499+
} else if (input_char == KEY_ARROW_UP || input_char == KEY_ARROW_DOWN) {
500+
// TODO: Implement history navigation
501+
#endif
465502
} else if (input_char == 0x08 || input_char == 0x7F) { // Backspace
466503
if (char_pos > 0) {
467504
int w = widths[char_pos - 1];

0 commit comments

Comments
 (0)