Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions experiments/shell/keyboard.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,30 @@ class KeyboardEncoder {
return {true, modifier == 1 ? std::string("\x1b[") + final :
std::string("\x1b[1;") + std::to_string(modifier) + final, false};
}
// F1..F4 use the SS3 letters; F5 and later use the xterm tilde numbers.
// The tilde numbers follow the VT/xterm table rather than the physical
// order so that applications see the same codes as other terminals.
static constexpr char ss3_function[] = {'P', 'Q', 'R', 'S'};
if (key >= 0x70 && key <= 0x73)
if (key >= 0x70 && key <= 0x73) {
const char letter = ss3_function[key - 0x70];
if (modifier == 1) return {true, std::string("\x1bO") + letter, false};
return {true, std::string("\x1b[1;") + std::to_string(modifier) + letter, false};
}
int number = 0;
switch (key) {
case 0x2d: number = 2; break; // Insert
case 0x2e: number = 3; break; // Delete
case 0x21: number = 5; break; // PageUp
case 0x22: number = 6; break; // PageDown
case 0x74: number = 15; break; // F5
case 0x75: number = 17; break; // F6
case 0x76: number = 18; break; // F7
case 0x77: number = 19; break; // F8
case 0x78: number = 20; break; // F9
case 0x79: number = 21; break; // F10
case 0x7a: number = 23; break; // F11
case 0x7b: number = 24; break; // F12
default: return {};
}
return {true, "\x1b[" + std::to_string(number) +
Expand Down
12 changes: 12 additions & 0 deletions experiments/shell/keyboard_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,18 @@ int main() {
"application mode must not rewrite modified cursor keys");
check(KeyboardEncoder::key_down(0x2e, {}, true).bytes == "\x1b[3~",
"application mode must not rewrite editing keys");
// F1..F4 are SS3 letters; F5..F12 use the xterm tilde numbers.
const std::vector<std::pair<uint32_t,std::string>> functions{
{0x70,"\x1bOP"}, {0x71,"\x1bOQ"}, {0x72,"\x1bOR"}, {0x73,"\x1bOS"},
{0x74,"\x1b[15~"}, {0x75,"\x1b[17~"}, {0x76,"\x1b[18~"}, {0x77,"\x1b[19~"},
{0x78,"\x1b[20~"}, {0x79,"\x1b[21~"}, {0x7a,"\x1b[23~"}, {0x7b,"\x1b[24~"}};
for (const auto& entry : functions) {
const auto encoded = KeyboardEncoder::key_down(entry.first);
check(encoded.handled && encoded.bytes == entry.second && !encoded.skip_translate,
"function key encoding");
}
check(KeyboardEncoder::key_down(0x70, {false,true,false,false}).bytes == "\x1b[1;5P",
"modified F1 must use the CSI modifier form");
check(KeyboardEncoder::key_down(0x24, {false,true,false,false}).bytes == "\x1b[1;5H", "Ctrl Home");
check(KeyboardEncoder::key_down(0x2e, {true,false,true,false}).bytes == "\x1b[3;4~", "Shift Alt Delete");
check(!KeyboardEncoder::key_down(0x09).handled, "plain Tab belongs only to WM_CHAR");
Expand Down
Loading