From c6d99559b547dcb4546363389bc0c5f8b63ff92d Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Mon, 12 Jul 2021 19:58:09 +0200 Subject: [PATCH] Better cli : arrows and edition --- src/cli.c | 79 ++++++++++++++++++++++++++++++++++++++++++++-------- src/server.c | 3 ++ 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/src/cli.c b/src/cli.c index 45f63b3..9276db0 100644 --- a/src/cli.c +++ b/src/cli.c @@ -39,8 +39,16 @@ #define KEY_DIRECTIONS 91 #define KEY_ARROW_UP 65 #define KEY_ARROW_DOWN 66 +#define KEY_ARROW_RIGHT 67 +#define KEY_ARROW_LEFT 68 #define KEY_DELETE 127 +#define C_CLEARLINE "\e[2K" +#define C_CURSORLEFT "\e[1D" +#define C_CURSORRIGHT "\e[1C" +#define C_SAVE_CURSORPOS "\e7" +#define C_RESTORE_CURSORPOS "\e8" + static char getch(void) { char buf = 0; @@ -90,7 +98,7 @@ void connectedCommunication(int sockfd) int historyIndex = 0, historyModifier; char curChar; - int curLineLength, continueReadLine, answerLength; + int curLineLength, curPosition, continueReadLine, answerLength; char *exitCommand = "exit"; char *promptString = "gem-graph console> "; @@ -102,9 +110,10 @@ void connectedCommunication(int sockfd) // Read command from terminal curLineLength = 0; + curPosition = 0; continueReadLine = 1; historyModifier = -1; - while (continueReadLine && (curChar = getch())) { //TODO empty line in history + while (continueReadLine && (curChar = getch())) { switch (curChar) { @@ -114,17 +123,31 @@ void connectedCommunication(int sockfd) break; case KEY_DELETE: - - if (!strlen(sendBuff)) + if (strlen(sendBuff) == 0) break; // Delete last char - sendBuff[--curLineLength] = 0; + sendBuff[--curPosition] = 0; + curLineLength--; - printf("\33[2K\r%s%s", + if (curLineLength >= 0) { + + printf("%s", C_SAVE_CURSORPOS); + + memmove(sendBuff + curPosition, sendBuff + curPosition + 1, + SEND_BUFFER_SIZE); + + //sendBuff[curLineLength--] = 0; + + printf("%s\r%s%s", + C_CLEARLINE, promptString, sendBuff ); + + printf("%s", C_RESTORE_CURSORPOS); + printf("%s", C_CURSORLEFT); + } break; case KEY_ESCAPE: @@ -137,7 +160,8 @@ void connectedCommunication(int sockfd) break; historyModifier = (historyModifier + 1) % (historyIndex + 1); - printf("\33[2K\r%s%s", + printf("%s\r%s%s", + C_CLEARLINE, promptString, &historyBuff[ (historyIndex - historyModifier - 1) @@ -149,15 +173,16 @@ void connectedCommunication(int sockfd) * SEND_BUFFER_SIZE ], SEND_BUFFER_SIZE); curLineLength = strlen(sendBuff); + curPosition = curLineLength; break; case KEY_ARROW_DOWN: - if (historyIndex <= 0) break; historyModifier = (historyModifier + historyIndex) % (historyIndex + 1); - printf("\33[2K\r%s%s", + printf("%s\r%s%s", + C_CLEARLINE, promptString, &historyBuff[ (historyIndex - historyModifier - 1) @@ -169,16 +194,46 @@ void connectedCommunication(int sockfd) * SEND_BUFFER_SIZE ], SEND_BUFFER_SIZE); curLineLength = strlen(sendBuff); + curPosition = curLineLength; + break; + + case KEY_ARROW_LEFT: + if (curPosition > 0) { + printf("%s", C_CURSORLEFT); + curPosition--; + } + break; + + case KEY_ARROW_RIGHT: + if (curPosition < curLineLength) { + printf("%s", C_CURSORRIGHT); + curPosition++; + } break; } } break; default: - sendBuff[curLineLength++] = curChar; - printf("%c", curChar); - break; + if (curLineLength < SEND_BUFFER_SIZE) { + printf("%s", C_SAVE_CURSORPOS); + memmove(sendBuff + curPosition + 1, sendBuff + curPosition, + SEND_BUFFER_SIZE); + + sendBuff[curPosition++] = curChar; + curLineLength++; + + printf("%s\r%s%s", + C_CLEARLINE, + promptString, + sendBuff + ); + + printf("%s", C_RESTORE_CURSORPOS); + printf("%s", C_CURSORRIGHT); + } + break; } fflush(stdout); diff --git a/src/server.c b/src/server.c index af13a26..90a953c 100644 --- a/src/server.c +++ b/src/server.c @@ -87,6 +87,9 @@ void *serverCommunicationInstance(void *server) clientPort, receiveBuff); + if (receiveBuff[0] == '\0') + break; + // get args in an array tokenIndex = 0; argv = (char**) realloc(argv, 1 * sizeof(char*));