ESH

Executive Shell
git clone http://git.omkov.net/ESH
Log | Tree | Refs | README | Download

AuthorJamozed <[email protected]>
Date2021-03-30 00:00:30
Commit826f57a64a662e1df99120bb167f42096d70a104
Parentc8190010e7d68c517e6d85040f0bcbba4d645252

Handle CTRL + W and DELETE inputs

Diffstat

M src/exec.c | 1 +
M src/lineread.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++-------------------

2 files changed, 49 insertions, 19 deletions

diff --git a/src/exec.c b/src/exec.c
index 2a22041..3817465 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -37,6 +37,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 #include <unistd.h>
 
 #include <errno.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
diff --git a/src/lineread.c b/src/lineread.c
index 77f23e8..5b60696 100644
--- a/src/lineread.c
+++ b/src/lineread.c
@@ -63,9 +63,10 @@ static void lineMoveLeft(struct line *l);
 static void lineMoveRight(struct line *l);
 static void lineMoveHome(struct line *l);
 static void lineMoveEnd(struct line *l);
-static int lineInsert(struct line *l, char c);
+static int  lineInsert(struct line *l, char c);
 static void lineBackspace(struct line *l);
 static void lineDelete(struct line *l);
+static void lineDeleteWord(struct line *l);
 
 /* Read a line from stdin */
 char *lineread(void) {
@@ -76,7 +77,7 @@ char *lineread(void) {
 
 /* Dynamically read a line from stdin */
 static char *lineedit(void) {
-	struct line l;
+	struct line l; register char *r;
 
 	l.sp = 0; l.sl = 0; l.sc = 1024; l.hi = 0;
 	l.prompt = "$ "; l.pl = strlen(l.prompt);
@@ -91,31 +92,48 @@ static char *lineedit(void) {
 		// printf("%02X\n", c); continue;
 
 		switch (c) {
-		case '\x01': { lineMoveHome(&l); continue; }  // CTRL + A
-		case '\x02': { lineMoveLeft(&l); continue; }  // CTRL + B
-		case '\x04': { tcrestore(); return NULL; }    // CTRL + D
-		case '\x05': { lineMoveEnd(&l); continue; }   // CTRL + E
-		case '\x06': { lineMoveRight(&l); continue; } // CTRL + F
+		case '\x01': { lineMoveHome(&l); continue; }   // CTRL + A
+		case '\x02': { lineMoveLeft(&l); continue; }   // CTRL + B
+		case '\x04': { r = NULL; goto ret; }           // CTRL + D
+		case '\x05': { lineMoveEnd(&l); continue; }    // CTRL + E
+		case '\x06': { lineMoveRight(&l); continue; }  // CTRL + F
 		case '\x0A': { goto end; }
-		case '\x0C': { clearscreen(&l); continue; }   // CTRL + L
-		case '\x1B': { int s[4];
-			if ((s[0] = fgetc(stdin)) == EOF) { break; }
-			if ((s[1] = fgetc(stdin)) == EOF) { break; }
-			
-			if (s[0] == '[') switch (s[1]) {
-			case 'A': { continue; } case 'B': { continue; }
-			case 'C': { lineMoveRight(&l); continue; }
-			case 'D': { lineMoveLeft(&l); continue; }
+		case '\x0C': { clearscreen(&l); continue; }    // CTRL + L
+		case '\x17': { lineDeleteWord(&l); continue; } // CTRL + W
+		case '\x1B': switch ((c = fgetc(stdin))) {
+			case '[': switch ((c = fgetc(stdin))) {
+				case '2': switch ((c = fgetc(stdin))) {
+					case '~': { /* TODO */
+						printf("%c", fgetc(stdin));
+						continue;
+					} // INSERT
+				}
+				case '3': switch ((c = fgetc(stdin))) {
+					case '~': { lineDelete(&l); continue; } // DELETE
+				}
+				case '5': switch ((c = fgetc(stdin))) {
+					case '~': { /* TODO */ continue; } // PGUP
+				}
+				case '6': switch ((c = fgetc(stdin))) {
+					case '~': { /* TODO */ continue; } // PGDOWN
+				}
+				case 'A': { /* TODO */ continue; } // UP
+				case 'B': { /* TODO */ continue; } // DOWN
+				case 'C': { lineMoveRight(&l); continue; }  // RIGHT
+				case 'D': { lineMoveLeft(&l); continue; }   // LEFT
+				case 'F': { lineMoveEnd(&l); continue; }    // END
+				case 'H': { lineMoveHome(&l); continue; }   // HOME
 			}
 		}
-		case '\x7F': { lineBackspace(&l); continue; }
+		case '\x7F': { lineBackspace(&l); continue; }  // BACKSPACE
 		default: { lineInsert(&l, c); }
 		}
 	}
 
 end:;
-	register char *s = strndup(l.s, l.sl);
-	free(l.s); tcrestore(); return s;
+	r = strndup(l.s, l.sl);
+ret:;
+	free(l.s); tcrestore(); return r;
 }
 
 /* Put stdin into raw mode */
@@ -200,3 +218,14 @@ static void lineDelete(struct line *l) {
 		l->s[--l->sl] = 0; lineRefresh(l);
 	} return;
 }
+
+/* Delete the word preceeding the cursor */
+static void lineDeleteWord(struct line *l) {
+	size_t p = l->sp;
+	
+	for (; l->sp && l->s[l->sp - 1] == ' '; --l->sp);
+	for (; l->sp && l->s[l->sp - 1] != ' '; --l->sp);
+	
+	memmove(l->s + l->sp, l->s + p, l->sl - p + 1);
+	l->sl -= p - l->sp; lineRefresh(l);
+}