|
@@ -0,0 +1,116 @@
|
|
|
|
+#include <ctype.h>
|
|
|
|
+#include <stdio.h>
|
|
|
|
+#include <stdlib.h>
|
|
|
|
+#include <termios.h>
|
|
|
|
+#include <unistd.h>
|
|
|
|
+
|
|
|
|
+// https://viewsourcecode.org/snaptoken/kilo/02.enteringRawMode.html
|
|
|
|
+
|
|
|
|
+struct termios orig_termios;
|
|
|
|
+
|
|
|
|
+void disableRawMode() {
|
|
|
|
+ tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void enableRawMode() {
|
|
|
|
+ tcgetattr(STDIN_FILENO, &orig_termios);
|
|
|
|
+ atexit(disableRawMode);
|
|
|
|
+
|
|
|
|
+ struct termios raw;
|
|
|
|
+ tcgetattr(STDIN_FILENO, &raw);
|
|
|
|
+ raw.c_iflag &= ~(ICRNL | IXON);
|
|
|
|
+ raw.c_lflag &= ~(ECHO | ICANON | IEXTEN /*| ISIG*/);
|
|
|
|
+ raw.c_cc[VMIN] = 0;
|
|
|
|
+ raw.c_cc[VTIME] = 0;
|
|
|
|
+
|
|
|
|
+ tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+char buffer[256];
|
|
|
|
+int move = 0;
|
|
|
|
+
|
|
|
|
+void refreshLine() {
|
|
|
|
+ putchar('\r');
|
|
|
|
+ printf("> %s", buffer);
|
|
|
|
+ if(move > 0) {
|
|
|
|
+ printf("\33[%dD", move);
|
|
|
|
+ }
|
|
|
|
+ fflush(STDIN_FILENO);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int main() {
|
|
|
|
+ enableRawMode();
|
|
|
|
+
|
|
|
|
+ int index = 0;
|
|
|
|
+ buffer[0] = '\0';
|
|
|
|
+
|
|
|
|
+ while(1) {
|
|
|
|
+ int c = 0;
|
|
|
|
+ int bytes = read(STDIN_FILENO, &c, 1);
|
|
|
|
+
|
|
|
|
+ printf("\33[2K\r");
|
|
|
|
+
|
|
|
|
+ if(bytes < 0) {
|
|
|
|
+ break;
|
|
|
|
+ } else if(bytes == 0) {
|
|
|
|
+ //printf("timeout\n");
|
|
|
|
+ refreshLine();
|
|
|
|
+ continue;
|
|
|
|
+ } else if(c == 'q') {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(c == 27) {
|
|
|
|
+ char escape[10];
|
|
|
|
+ int escapeBytes = read(STDIN_FILENO, escape, 10);
|
|
|
|
+ printf("Escape sequence of length: %d\n", escapeBytes);
|
|
|
|
+ if(escapeBytes == 2) {
|
|
|
|
+ if(escape[0] == '[' && escape[1] == 'D' && move < index) {
|
|
|
|
+ move++;
|
|
|
|
+ }
|
|
|
|
+ if(escape[0] == '[' && escape[1] == 'C' && move > 0) {
|
|
|
|
+ move--;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(iscntrl(c)) {
|
|
|
|
+ switch(c) {
|
|
|
|
+ case 127:
|
|
|
|
+ if(index > 0) {
|
|
|
|
+ if(move == 0) {
|
|
|
|
+ index--;
|
|
|
|
+ buffer[index] = '\0';
|
|
|
|
+ } else {
|
|
|
|
+ int pos = index - move - 1;
|
|
|
|
+ if(pos >= 0) {
|
|
|
|
+ while(buffer[pos] != '\0') {
|
|
|
|
+ buffer[pos] = buffer[pos + 1];
|
|
|
|
+ pos++;
|
|
|
|
+ }
|
|
|
|
+ index--;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+ case 13:
|
|
|
|
+ puts(buffer);
|
|
|
|
+ index = 0;
|
|
|
|
+ buffer[0] = '\0';
|
|
|
|
+ move = 0;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ printf("%d\n", c);
|
|
|
|
+ } else {
|
|
|
|
+ printf("%d ('%c')\n", c, c);
|
|
|
|
+ if(move == 0) {
|
|
|
|
+ buffer[index++] = c;
|
|
|
|
+ buffer[index] = '\0';
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ refreshLine();
|
|
|
|
+ }
|
|
|
|
+ return 0;
|
|
|
|
+}
|