diff options
Diffstat (limited to 'TUI/module.jai')
| -rw-r--r-- | TUI/module.jai | 79 |
1 files changed, 68 insertions, 11 deletions
diff --git a/TUI/module.jai b/TUI/module.jai index 4e87589..73f9260 100644 --- a/TUI/module.jai +++ b/TUI/module.jai @@ -71,8 +71,8 @@ Commands :: struct { // Cursor Visibility ShowCursor :: "\e[?25h"; HideCursor :: "\e[?25l"; - StartBlinking :: "\e[?25h]"; - StopBlinking :: "\e[?25l]"; + StartBlinking :: "\e[?25h"; + StopBlinking :: "\e[?25l"; SaveCursorPosition :: "\e7"; RestoreCursorPosition :: "\e8"; @@ -349,7 +349,7 @@ to_key :: inline (str: $T) -> Key #modify { return T == ([]u8) || T == string; } return k; } -to_string :: inline (key: Key) -> string { +to_string :: inline (key: Key) -> string { // TODO FIXME TEMPORARY MEMORY str := talloc_string(KEY_SIZE); str.count = 0; while key != 0 #no_abc { @@ -360,6 +360,15 @@ to_string :: inline (key: Key) -> string { return str; } +is_escape_code :: inline (key: Key) -> bool { + result := false; + while key != 0 { + key >>= 8; + result |= ((key ^ Keys.Escape) == 0); + } + return result; +} + // TODO FIXME DEBUG HACK test_union :: () { @@ -573,31 +582,79 @@ get_string :: (count_limit: int = -1) -> string { } // TODO UNTESTED -user_line_input :: (count_limit: int = -1, is_visible: bool = true) -> string, Key { +// TODO Is count_limit the number of bytes of UTF8 symbols? +user_line_input :: (count_limit: int, is_visible: bool = true) -> string, Key { + assert(count_limit >= 0, "Invalid value on count_limit parameter."); + str := alloc_string(count_limit); // TODO Show blinking cursor + write_strings(Commands.StartBlinking, Commands.BlinkingUnderlineShape); + row, col := get_cursor_position(); + idx := 0; key := Keys.None; - builder: String_Builder; - init_string_builder(*builder); + + // TODO Some of these may be nice to have: + // > https://unix.stackexchange.com/questions/255707/what-are-the-keyboard-shortcuts-for-the-command-line while key != Keys.Resize && key != Keys.Escape { // TODO How to alloc/release temporary memory here? key = get_key(); - if key == Keys.Enter then break; - str := to_string(key); - print("%", str); - print_to_builder(*builder, "%", str); + + if key == { + case Keys.Enter; + break; + + case Keys.Left; + if idx == 0 continue; + idx -= 1; + + case Keys.Right; + if idx == str.count-1 continue; + idx += 1; + + case Keys.Delete; + if idx == str.count-1 continue; + for idx..str.count-2 { + str.data[it] = str.data[it+1]; + } + + case Keys.Backspace; + if idx == 0 continue; + idx -= 1; + for idx..str.count-2 { + str.data[it] = str.data[it+1]; + } + + case; + if is_escape_code(key) continue; - TODO NOT WORKING FIX THIS + key_str := to_string(key); + str.data[idx] = key_str.data[0]; + idx += 1; + } + + + // append(*builder, str); + // set_cursor_position(row, col); + // write_builder(*builder, false); + set_cursor_position(row, col+idx); + for idx..count_limit print_character(#char " "); + set_cursor_position(row, col); + write_string(str); + // print(">%<", builder_to_string(*builder,, temporary_allocator)); + set_cursor_position(row, col+idx); } + write_strings(Commands.StopBlinking, Commands.DefaultShape); /* Use the get_key to read user input and show it on screen... should allow to move the cursor left and right and to delete/backspace. Enter should end the input, returning the input string and the Enter key. Escape should discard the input returning an empty string and a None key. Resize should discard the input returning an empty string and a Resize key. */ - result := ifx key == Keys.Enter then builder_to_string(*builder) else ""; + // result := ifx key == Keys.Enter then builder_to_string(*builder) else ""; + result := ifx key == Keys.Enter then str else ""; return result, key; } |
