blob: fdb61a19516e4da216afed379c789708021e7ad3 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
#include <libterm/terminal.h>
#include <knob/block.h>
#include <knob/key.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) {
term_add_sz(prompt);
term_add_char(' ');
term_paint();
uint32_t l = 0;
uint32_t c = 0;
while (1) {
struct key_packet kp = term_get_key_blocking();
switch (kp.key_id) {
case KEY_LEFT_ARROW:
if (c) {
--c;
term_cursor_left();
term_paint();
}
continue;
case KEY_RIGHT_ARROW:
if (c != l) {
++c;
term_cursor_right();
term_paint();
}
continue;
case KEY_HOME:
while (c) {
--c;
term_cursor_left();
}
term_paint();
continue;
case KEY_END:
while (c != l) {
++c;
term_cursor_right();
}
term_paint();
continue;
case KEY_DELETE:
if (c != l) {
++c;
term_cursor_right();
}
case KEY_BSPACE:
if (!c)
continue;
--c;
--l;
for (uint32_t i = c; i < l; ++i)
sz[i] = sz[i + 1];
term_cursor_left();
term_add_sn_no_ww(sz + c, l - c);
term_add_char(' ');
for (uint32_t i = l + 1; i > c; --i)
term_cursor_left();
term_paint();
continue;
case KEY_ENTER:
while (c != l) {
++c;
term_cursor_right();
}
sz[l] = '\0';
term_add_char('\n');
term_paint();
_yield_task();
return l;
default:
if (l == max_length)
continue;
char ch = key_to_char(kp);
if (!ch)
continue;
if (c == l) {
++l;
term_add_char(sz[c++] = ch);
term_paint();
continue;
}
if (!(kp.modifiers & INSERT)) {
term_add_char(sz[c++] = ch);
term_paint();
continue;
}
for (uint32_t i = l; i > c; --i)
sz[i] = sz[i - 1];
sz[c] = ch;
++l;
term_add_sn_no_ww(sz + c, l - c);
++c;
for (uint32_t i = l; i > c; --i)
term_cursor_left();
term_paint();
continue;
}
}
}
|