diff options
Diffstat (limited to 'ttwhy/scanners/terminal_policies.cppm')
| -rw-r--r-- | ttwhy/scanners/terminal_policies.cppm | 180 |
1 files changed, 136 insertions, 44 deletions
diff --git a/ttwhy/scanners/terminal_policies.cppm b/ttwhy/scanners/terminal_policies.cppm index e5863d3..bf7c126 100644 --- a/ttwhy/scanners/terminal_policies.cppm +++ b/ttwhy/scanners/terminal_policies.cppm @@ -1,70 +1,162 @@ module; +#include <optional> #include <string> export module ttwhy.scanners:terminal_policies; -import :events; -import :concepts; +import :terminal_events; +import :terminal_concepts; namespace ttwhy::scanners { + namespace detail + { + constexpr auto map_vt220_keypad(char terminator) -> std::optional<navigation_key> + { + switch (terminator) + { + case '1': + case '7': + return navigation_key::home; + case '2': + return navigation_key::insert_key; + case '3': + return navigation_key::delete_key; + case '4': + case '8': + return navigation_key::end; + case '5': + return navigation_key::page_up; + case '6': + return navigation_key::page_down; + default: + return std::nullopt; + } + } + + constexpr auto map_vt100_cursor(char terminator) -> std::optional<navigation_key> + { + switch (terminator) + { + case 'A': + return navigation_key::up; + case 'B': + return navigation_key::down; + case 'C': + return navigation_key::right; + case 'D': + return navigation_key::left; + case 'H': + return navigation_key::home; + case 'F': + return navigation_key::end; + default: + return std::nullopt; + } + } + + } // namespace detail + + export template<typename T> + using associated_terminal_policy_t = typename T::terminal_policy; + export struct ansi_policy { constexpr auto static resolve_vt220_keypad(std::string & buffer, ttwhy::ansi_sink auto & sink) -> void { - auto key = [](auto terminator) { - switch (terminator) - { - case '1': - case '7': - return navigation_key::home; - case '2': - return navigation_key::insert_key; - case '3': - return navigation_key::delete_key; - case '4': - case '8': - return navigation_key::end; - case '5': - return navigation_key::page_up; - case '6': - return navigation_key::page_down; - default: - return static_cast<navigation_key>(-1); - } - }(buffer.back()); - sink(navigation_event{key}); + if (buffer.empty()) + { + return; + } + + if (auto key = detail::map_vt220_keypad(buffer.front())) + { + sink(navigation_event{*key}); + } + buffer.clear(); } - constexpr auto static resolve_vt100_cursor(char terminator, ttwhy::ansi_sink auto & sink) -> void + constexpr auto static resolve_vt100_cursor(char terminator, std::string &, ttwhy::ansi_sink auto & sink) -> void { - auto key = [terminator] { - switch (terminator) + if (auto key = detail::map_vt100_cursor(terminator)) + { + sink(navigation_event{*key}); + } + } + + constexpr auto static resolve_ss3(char terminator, ttwhy::ansi_sink auto & sink) -> void + { + if (auto key = detail::map_vt100_cursor(terminator)) + { + sink(navigation_event{*key}); + } + } + }; + + export struct xterm_policy + { + constexpr auto static parse_modifiers(std::string_view buffer) -> modifier_set + { + auto delimiter = buffer.find(';'); + if (delimiter == std::string_view::npos) + { + return {}; + } + + auto modifier_string = buffer.substr(delimiter + 1); + auto modifier_value = 0u; + + for (auto character : modifier_string) + { + if (character >= '0' && character <= '9') { - case 'A': - return navigation_key::up; - case 'B': - return navigation_key::down; - case 'C': - return navigation_key::right; - case 'D': - return navigation_key::left; - case 'H': - return navigation_key::home; - case 'F': - return navigation_key::end; - default: - return static_cast<navigation_key>(-1); + modifier_value = modifier_value * 10 + static_cast<unsigned int>(character - '0'); } - }(); - sink(navigation_event{key}); + } + + if (modifier_value <= 1) + { + return {}; + } + + return static_cast<modifier_set>(modifier_value - 1); + } + + constexpr auto static resolve_vt220_keypad(std::string & buffer, ttwhy::ansi_sink auto & sink) -> void + { + if (buffer.empty()) + { + return; + } + + auto modifiers = parse_modifiers(buffer); + + if (auto key = detail::map_vt220_keypad(buffer.front())) + { + sink(navigation_event{*key, modifiers}); + } + buffer.clear(); + } + + constexpr auto static resolve_vt100_cursor(char terminator, std::string & buffer, ttwhy::ansi_sink auto & sink) + -> void + { + auto modifiers = parse_modifiers(buffer); + + if (auto key = detail::map_vt100_cursor(terminator)) + { + sink(navigation_event{*key, modifiers}); + } } constexpr auto static resolve_ss3(char terminator, ttwhy::ansi_sink auto & sink) -> void { - return resolve_vt100_cursor(terminator, sink); + if (auto key = detail::map_vt100_cursor(terminator)) + { + sink(navigation_event{*key}); + } } }; |
