#include #include char* freadln(FILE f) { fprint(f, "\x1b[e"); // enable keyboard echo int i; char *p = (char*)malloc(256); char *b = p; while (1) { int l = read(f, 0, 255, b); if (l < 0) { free(b); return 0; } for (i = 0; i < l; i++) { if (b[i] == '\n') { b[i+1] = 0; return p; } else if (b[i] == 27) { // ignore escape sequences b[i] = 0; l = i; } } int d = b - p + l; char* newp = (char*)malloc(d + 256); memcpy(newp, p, d); free(p); p = newp; b = p + d; } } // ** READLINE char *readline(FILE f, readline_history *h) { int i; fprint(f, "\x1b[h"); // disable keyboard echo if (h->str == 0) { h->str = (char**)malloc(h->max * sizeof(char*)); for (i = 0; i < h->max; i++) h->str[i] = 0; h->n = 0; } int lid; if (h->n < h->max) { lid = h->n++; } else { free(h->str[0]); int i; for (i = 0; i < h->max - 1; i++) { h->str[i] = h->str[i+1]; } lid = h->max - 1; h->str[lid] = 0; } if (h->str[lid] == 0) h->str[lid] = (char*)malloc(256); char *str = h->str[lid]; str[0] = 0; char *cur = str; // position in string int len = 0; // string length while (1) { int finished = 0; int te = cur - str; char buf[16]; int l = read(f, 0, 16, buf); if (l < 0) return 0; if (buf[0] == 27) { if (buf[1] == '[') { if (buf[2] == 'A') { // up if (lid > 0) { lid--; str = h->str[lid]; len = strlen(str); cur = str + len; } } else if (buf[2] == 'B') { // down if (lid < h->n - 1) { lid++; str = h->str[lid]; len = strlen(str); cur = str + len; } } else if (buf[2] == 'C') { // forward (right) if (cur < str + len) cur++; } else if (buf[2] == 'D') { // back (left) if (cur > str) cur--; } } else { // ALT sequence - ignore } } else if (buf[0] == '\n') { finished = 1; cur = str + len; } else if (buf[0] == '\b') { if (cur > str) { cur--; len--; char* c; for (c = cur; *c != 0; c++) c[0] = c[1]; } } else if (buf[0] == '\t') { // ignore tabs -- todo: tab completion???? haha } else if (buf[0] >= ' ') { if (l < 255) { char* c; for (c = cur + len; c >= cur; c--) c[1] = c[0]; cur[0] = buf[0]; cur++; len++; } } // ASSUMPTION : everything will fit on one line... if (te > 0) fprintf(f, "\x1b[%iD", te); fprintf(f, "\x1b[K%s", str); te = len - (cur - str); if (te > 0) fprintf(f, "\x1b[%iD", te); if (finished) { fprintf(f, "\n"); if (h->str[h->n-1][0] == 0) h->n--; return str; } } }