diff options
Diffstat (limited to 'src/user/terminal/readline.c')
-rw-r--r-- | src/user/terminal/readline.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/user/terminal/readline.c b/src/user/terminal/readline.c new file mode 100644 index 0000000..37ef54b --- /dev/null +++ b/src/user/terminal/readline.c @@ -0,0 +1,104 @@ +#include <terminal/terminal.h> + +#include <knob/format.h> +#include <knob/heap.h> +#include <knob/key.h> + +#include <pland/syscall.h> + +#include <stdint.h> + +//returns length of string without null terminator +//max_length doesn't include null terminator +uint32_t read_line(char *sz, uint32_t max_length, const char *prompt) { + uint32_t i = 0; + uint32_t l = 0; + + term_add_sz_no_ww(prompt); + paint_term(); + + const _window_handle_t handle = active_term->window; + struct window_action action; + while (1) { + _get_win_action(handle, &action); + switch (action.action_type) { + case NOT_READY: + _wait_for_action(); + _yield_task(); + continue; + case KEY_DOWN: + //;char *const debug_msg = format("got key 0x%2x, 0x%3x", action.as_key.key_id, action.as_key.modifiers); + // _system_log(debug_msg); + // free_block(debug_msg); + switch (action.as_key.key_id) { + case KEY_DELETE: + if (i != l) { + cursor_right(); + ++i; + } + case KEY_BSPACE: + if (!i) + continue; + --l; + --i; + for (uint8_t j = i; j < l; ++j) + sz[j] = sz[j + 1]; + sz[l] = '\0'; + cursor_left(); + uint32_t cursor_backup_x = active_term->cursor_x; + uint32_t cursor_backup_y = active_term->cursor_y; + term_add_sz_no_ww(sz + i); + term_add_char(' '); + move_cursor(cursor_backup_y, cursor_backup_x); + paint_term(); + continue; + case KEY_ENTER: + term_newline(); + paint_term(); + sz[l] = '\0'; + return l; + case KEY_HOME: + case KEY_UP_ARROW: + for (; i; --i) + cursor_left(); + paint_term(); + continue; + case KEY_END: + case KEY_DOWN_ARROW: + for (; i != l; ++i) + cursor_right(); + paint_term(); + continue; + case KEY_LEFT_ARROW: + if (i) { + cursor_left(); + paint_term(); + --i; + } + continue; + case KEY_RIGHT_ARROW: + if (i != l) { + cursor_right(); + paint_term(); + ++i; + } + continue; + default: + if (i == max_length) + continue; + char ch = key_to_char(action.as_key); + if (ch) { + term_add_char(ch); + paint_term(); + sz[i] = ch; + if (i == l) + ++l; + ++i; + } + continue; + } + default: + continue; + } + } +}
\ No newline at end of file |