From e73e7f0d68de963269add77541d3d1462716f6a8 Mon Sep 17 00:00:00 2001
From: Stefan Ravn van Overeem <StefanRvO@users.noreply.github.com>
Date: Sun, 25 Jun 2023 17:11:59 +0200
Subject: [PATCH] Support Fn keys for every terminal standards (#689)

Co-authored-by: ArthurSonzogni <sonzogniarthur@gmail.com>
---
 src/ftxui/component/terminal_input_parser.cpp | 34 +++++++++++++++++++
 .../component/terminal_input_parser_test.cpp  | 28 +++++++++++++++
 2 files changed, 62 insertions(+)

diff --git a/src/ftxui/component/terminal_input_parser.cpp b/src/ftxui/component/terminal_input_parser.cpp
index cbf125e2..5dbd28e4 100644
--- a/src/ftxui/component/terminal_input_parser.cpp
+++ b/src/ftxui/component/terminal_input_parser.cpp
@@ -45,12 +45,46 @@ const std::map<std::string, std::string> g_uniformize = {
     {"\x1BOF", "\x1B[F"},  // END
 
     // Variations around the FN keys.
+    // Internally, we are using:
+    // vt220, xterm-vt200, xterm-xf86-v44, xterm-new, mgt, screen
+    // See: https://invisible-island.net/xterm/xterm-function-keys.html
+
+    // For linux OS console (CTRL+ALT+FN), who do not belong to any
+    // real standard.
     // See: https://github.com/ArthurSonzogni/FTXUI/issues/685
     {"\x1B[[A", "\x1BOP"},    // F1
     {"\x1B[[B", "\x1BOQ"},    // F2
     {"\x1B[[C", "\x1BOR"},    // F3
     {"\x1B[[D", "\x1BOS"},    // F4
     {"\x1B[[E", "\x1B[15~"},  // F5
+
+    // xterm-r5, xterm-r6, rxvt
+    {"\x1B[11~", "\x1BOP"},  // F1
+    {"\x1B[12~", "\x1BOQ"},  // F2
+    {"\x1B[13~", "\x1BOR"},  // F3
+    {"\x1B[14~", "\x1BOS"},  // F4
+
+    // vt100
+    {"\x1BOt", "\x1B[15~"},  // F5
+    {"\x1BOu", "\x1B[17~"},  // F6
+    {"\x1BOv", "\x1B[18~"},  // F7
+    {"\x1BOl", "\x1B[19~"},  // F8
+    {"\x1BOw", "\x1B[20~"},  // F9
+    {"\x1BOx", "\x1B[21~"},  // F10
+
+    // scoansi
+    {"\x1B[M", "\x1BOP"},    // F1
+    {"\x1B[N", "\x1BOQ"},    // F2
+    {"\x1B[O", "\x1BOR"},    // F3
+    {"\x1B[P", "\x1BOS"},    // F4
+    {"\x1B[Q", "\x1B[15~"},  // F5
+    {"\x1B[R", "\x1B[17~"},  // F6
+    {"\x1B[S", "\x1B[18~"},  // F7
+    {"\x1B[T", "\x1B[19~"},  // F8
+    {"\x1B[U", "\x1B[20~"},  // F9
+    {"\x1B[V", "\x1B[21~"},  // F10
+    {"\x1B[W", "\x1B[23~"},  // F11
+    {"\x1B[X", "\x1B[24~"},  // F12
 };
 
 TerminalInputParser::TerminalInputParser(Sender<Task> out)
diff --git a/src/ftxui/component/terminal_input_parser_test.cpp b/src/ftxui/component/terminal_input_parser_test.cpp
index 95fd4234..f037ac73 100644
--- a/src/ftxui/component/terminal_input_parser_test.cpp
+++ b/src/ftxui/component/terminal_input_parser_test.cpp
@@ -392,6 +392,34 @@ TEST(Event, Special) {
       {str("\x1B[[D"), Event::F4},
       {str("\x1B[[E"), Event::F5},
 
+      // Function keys for xterm-r5, xterm-r6, rxvt
+      {str("\x1B[11~"), Event::F1},
+      {str("\x1B[12~"), Event::F2},
+      {str("\x1B[13~"), Event::F3},
+      {str("\x1B[14~"), Event::F4},
+
+      // Function keys for vt100
+      {str("\x1BOt"), Event::F5},
+      {str("\x1BOu"), Event::F6},
+      {str("\x1BOv"), Event::F7},
+      {str("\x1BOl"), Event::F8},
+      {str("\x1BOw"), Event::F9},
+      {str("\x1BOx"), Event::F10},
+
+      // Function keys for scoansi
+      {str("\x1B[M"), Event::F1},
+      {str("\x1B[N"), Event::F2},
+      {str("\x1B[O"), Event::F3},
+      {str("\x1B[P"), Event::F4},
+      {str("\x1B[Q"), Event::F5},
+      {str("\x1B[R"), Event::F6},
+      {str("\x1B[S"), Event::F7},
+      {str("\x1B[T"), Event::F8},
+      {str("\x1B[U"), Event::F9},
+      {str("\x1B[V"), Event::F10},
+      {str("\x1B[W"), Event::F11},
+      {str("\x1B[X"), Event::F12},
+
       // Page up and down:
       {str("\x1B[5~"), Event::PageUp},
       {str("\x1B[6~"), Event::PageDown},
-- 
GitLab