diff --git a/src/geadline.🗿 b/src/geadline.🗿 index 935c8e9..974650a 100644 --- a/src/geadline.🗿 +++ b/src/geadline.🗿 @@ -3,11 +3,13 @@ geadline(prompt) { size = 0, i = 0, c, + a, buf = galloc(capacity); if (prompt) putstr(prompt); if (buf == NULL) return NULL; + [buf] = 0; loop { red &c; @@ -16,34 +18,94 @@ geadline(prompt) { free(buf); return 0; } - } else if (c == 0x007f) { - if (size) { + } else if (c == 0x1b) { + // ESC code + red &c; // skip [ + red &c; // value + + if ((c == 'A') & (size > 0)) { + loop { + if (i == 0) + break; + i = i - 1; + esccode('D'); + } + } else if ((c == 'B') & (i < size)) { + loop { + if (i >= size) + break; + i = i + 1; + esccode('C'); + } + } else if ((c == 'C') & (i < size)) { + i = i + 1; + esccode('C'); + } else if ((c == 'D') & (i > 0)) { + i = i - 1; + esccode('D'); + } + wrt '\a'; + } else if (c == 0x7f) { + if (i) { + a = i - 1; + loop { + if (a >= size) + break; + [buf + a] = [buf + a + 1]; + a = a + 1; + } size = size - 1; i = i - 1; [buf + size] = 0; - wrt 0x1b; - wrt 0x5b; - wrt 0x44; + wrt '\r'; + if (prompt) + putstr(prompt); + putstr(buf); wrt ' '; - wrt 0x1b; - wrt 0x5b; - wrt 0x44; + esccode('D'); + a = size - i; + loop { + if (a == 0) + break; + a = a - 1; + esccode('D'); + } } } else { size = size + 1; - if (size > capacity) { + if (size >= capacity) { buf = realloc(buf, capacity * 2); if (buf == NULL) return NULL; capacity = capacity * 2; } + a = size - i - 1; + loop { + if ((a == 0xffff) | (a == 0)) + break; + [buf + i + a] = [buf + i + a - 1]; + a = a - 1; + } [buf + i] = c; + [buf + size] = 0; + putstr(buf + i); + a = strlen(buf + i) - 1; + loop { + if ((a == 0xffff) | (a == 0)) + break; + a = a - 1; + esccode('D'); + } i = i + 1; - [buf + i] = 0; - wrt c; if (c == '\n') return buf; } } } + +esccode(c) { + wrt 0x1b; + wrt '['; + wrt c; +}