diff --git a/CHANGELOG.md b/CHANGELOG.md index 209b139..3588981 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Changelog --- ### Component +- Bugfix: Support F1-F5 from OS terminal. ### Dom - Feature: Add `hyperlink` decorator. For instance: diff --git a/src/ftxui/component/terminal_input_parser.cpp b/src/ftxui/component/terminal_input_parser.cpp index 208f16f..faa4b7b 100644 --- a/src/ftxui/component/terminal_input_parser.cpp +++ b/src/ftxui/component/terminal_input_parser.cpp @@ -44,6 +44,13 @@ const std::map g_uniformize = { {"\x1BOH", "\x1B[H"}, // HOME {"\x1BOF", "\x1B[F"}, // END + // Variations around the FN keys. + // 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 }; TerminalInputParser::TerminalInputParser(Sender out) @@ -291,9 +298,16 @@ TerminalInputParser::Output TerminalInputParser::ParseCSI() { continue; } - if (Current() >= ' ' && Current() <= '~' && Current() != '<') { + // CSI is terminated by a character in the range 0x40–0x7E + // (ASCII @A–Z[\]^_`a–z{|}~), + if (Current() >= '@' && Current() <= '~' && + // Note: I don't remember why we exclude '<' + Current() != '<' && + // To handle F1-F4, we exclude '['. + Current() != '[') { arguments.push_back(argument); argument = 0; // NOLINT + switch (Current()) { case 'M': return ParseMouse(altered, true, std::move(arguments)); diff --git a/src/ftxui/component/terminal_input_parser_test.cpp b/src/ftxui/component/terminal_input_parser_test.cpp index 1b1a92c..a930ab2 100644 --- a/src/ftxui/component/terminal_input_parser_test.cpp +++ b/src/ftxui/component/terminal_input_parser_test.cpp @@ -384,6 +384,13 @@ TEST(Event, Special) { {str("\x1B[23~"), Event::F11}, {str("\x1B[24~"), Event::F12}, + // Function keys for virtual terminal: + {str("\x1B[[A"), Event::F1}, + {str("\x1B[[B"), Event::F2}, + {str("\x1B[[C"), Event::F3}, + {str("\x1B[[D"), Event::F4}, + {str("\x1B[[E"), Event::F5}, + // Page up and down: {str("\x1B[5~"), Event::PageUp}, {str("\x1B[6~"), Event::PageDown},