aboutsummaryrefslogtreecommitdiff
path: root/modules/TUI
diff options
context:
space:
mode:
authordam <dam@gudinoff>2024-03-21 00:50:42 +0000
committerdam <dam@gudinoff>2024-03-21 00:50:42 +0000
commitb47287aaa3cfa384ec683ff58e0d247e8bad32b1 (patch)
treeb838b1d21fbd1a36e27e129d75e2f3224b98df1e /modules/TUI
parentac92da96856603d450e39fa536f287bcf67c0fd7 (diff)
downloadtask-time-tracker-b47287aaa3cfa384ec683ff58e0d247e8bad32b1.tar.zst
task-time-tracker-b47287aaa3cfa384ec683ff58e0d247e8bad32b1.zip
Fix get_key to support escape codes.
Diffstat (limited to 'modules/TUI')
-rw-r--r--modules/TUI/key_map.jai2
-rw-r--r--modules/TUI/module.jai48
2 files changed, 18 insertions, 32 deletions
diff --git a/modules/TUI/key_map.jai b/modules/TUI/key_map.jai
index 42acabf..b272253 100644
--- a/modules/TUI/key_map.jai
+++ b/modules/TUI/key_map.jai
@@ -31,7 +31,7 @@ setup_key_map :: () {
*/
// Up // g i k l x
- // table_set(*key_map, "\e[A", to_key("#up")); // + + + + +
+ table_set(*key_map, "\e[A", to_key("#up")); // + + + + +
table_set(*key_map, "\e[1;1A", to_key("#up")); //
table_set(*key_map, "\e[1;2A", to_key("#up+$")); // + + + +
table_set(*key_map, "\e[1;3A", to_key("#up+a")); // + + + +
diff --git a/modules/TUI/module.jai b/modules/TUI/module.jai
index d93e4ff..93e410e 100644
--- a/modules/TUI/module.jai
+++ b/modules/TUI/module.jai
@@ -126,6 +126,8 @@ Colors8b :: struct {
White :: 15;
}
+// Fix color tables using this: https://devmemo.io/cheatsheets/terminal_escape_code/
+
// TODO Maybe rename.
set_style_colors :: (foreground: u8, background: u8) {
print(
@@ -261,15 +263,6 @@ set_next_key :: (key: Key) {
get_key :: (timeout_milliseconds: s32 = -1) -> Key {
assert_is_initialized();
- /*
- TODO
- get_key already deals with utf8 codes, but we don't know when we're receiving ANSI escape codes. If initial key is escape and other keys are awaiting in the input buffer, we need to parse them as escaped sequences. See wikiedia* for help on that. Lets use the escape sequences used on windows amd forget all others. Those should be the most used ones; at least they are the cross-platform compatible ones :P
- * https://en.m.wikipedia.org/wiki/ANSI_escape_code
-
- Check this
- https://devmemo.io/cheatsheets/terminal_escape_code/
- */
-
// BBBB BBBB & 1100 0000 == 10XX XXXX -> is continuation byte
is_utf8_continuation_byte :: inline (byte: u8) -> bool {
@@ -321,38 +314,31 @@ get_key :: (timeout_milliseconds: s32 = -1) -> Key {
if input_string.count == 0 return Keys.None;
- // Assume we're parsing just a single char.
+ // By default, parse a single UTF8 character (1 to 4 bytes).
to_parse := input_string;
- to_parse.count = 1;
-
- // Try to parse UTF8 character.
- if is_utf8_continuation_byte(input_string[0]) {
- to_parse.count = count_utf8_bytes(input_string[0]);
- }
-
+ to_parse.count = count_utf8_bytes(input_string[0]);
+ defer advance(*input_string, to_parse.count); // Advance over parsed input.
+
// Try to parse escape code.
if input_string[0] == #char "\e" && input_string.count > 1 {
- assert(input_string.count <= KEY_SIZE, "Received oversized terminal sequence."); // TODO
- to_parse.count = ifx input_string.count > KEY_SIZE then KEY_SIZE else input_string.count; // TODO We should look into the input_string and search for the following escape sequence or somehting!?
- // WIP HERE
- // A possible way to solve this is to create a LUT, and then, grow the to_parse.count from 2 to KEY_SIZE and return as soon
- // as we ding a match on the LUT.
- // If the LUT is too big... maybe use a hash-table.
+ // Limit number of chars to parse.
+ to_parse.count = ifx input_string.count > KEY_SIZE then KEY_SIZE else input_string.count;
- // TEMPORARY HACK
+ // Search for the longest escape code.
key, success := table_find(*key_map, to_parse);
+ while success == false && to_parse.count > 1 {
+ to_parse.count -= 1;
+ key, success = table_find(*key_map, to_parse);
+ }
+
+ // If an escape code was found, use it.
if success {
- advance(*input_string, to_parse.count);
return key;
}
- TODO If failed to parse... lets return a single char... but it's not working!
- else {
- to_parse.count = 1;
- }
+ // else { ... } If we entered this block and did not succeed, then we'll return a single escape character.รข
}
-
- advance(*input_string, to_parse.count);
+
return to_key(to_parse);
}