ESH

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

AuthorJamozed <[email protected]>
Date2021-03-31 23:37:12
Commitebc6a6fa1b0fa9db350cf5605951cdc3945a1e11
Parentf98c21adad6f645d5f2cf02a5bf6917c101b749f

Add various word processing functions

Diffstat

M src/lineread.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------

1 files changed, 94 insertions, 30 deletions

diff --git a/src/lineread.c b/src/lineread.c
index c8241b5..8e0b1fa 100644
--- a/src/lineread.c
+++ b/src/lineread.c
@@ -52,6 +52,7 @@ struct line {
 static struct termios tco, tcn;
 
 static char *lineedit(void);
+static void lineESC(struct line *l, register int c);
 
 static inline void tcraw(void);
 static inline void tcrestore(void);
@@ -61,12 +62,17 @@ static void clearscreen(struct line *l);
 static void lineRefresh(struct line *l);
 static void lineMoveLeft(struct line *l);
 static void lineMoveRight(struct line *l);
+static void lineMoveWordHome(struct line *l);
+static void lineMoveWordEnd(struct line *l);
 static void lineMoveHome(struct line *l);
 static void lineMoveEnd(struct line *l);
 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);
+static void lineDeleteWordHome(struct line *l);
+static void lineDeleteWordEnd(struct line *l);
+static void lineDeleteHome(struct line *l);
+static void lineDeleteEnd(struct line *l);
 
 /* Read a line from stdin */
 char *lineread(void) {
@@ -87,42 +93,51 @@ static char *lineedit(void) {
 
 	tcraw(); fputs(l.prompt, stdout);
 
-	for (int c; (c = fgetc(stdin));) {
+	for (register int c; (c = fgetc(stdin));) {
 		if (errno) { warn("%s", serr()); }
 		// printf("%02X\n", c); continue;
 
 		switch (c) {
-		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 '\x17': { lineDeleteWord(&l); continue; } // CTRL + W
+		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 '\x07': { continue; }                  // IGNORE CTRL + G
+		case '\x08': { lineBackspace(&l); continue; }      // CTRL + H
+		case '\x09': { continue; }                  // IGNORE CTRL + I
+		case '\x0A': { goto end; }                // ENTER or CTRL + J
+		case '\x0B': { lineDeleteEnd(&l); continue; }      // CTRL + K
+		case '\x0C': { clearscreen(&l); continue; }        // CTRL + L
+		case '\x0D': { continue; }                  // IGNORE CTRL + M
+		case '\x0E': { /* Next history */ continue; }      // CTRL + N
+		case '\x0F': { goto end; }                         // CTRL + O
+		case '\x10': { /* Prior history */ continue; }     // CTRL + P
+		case '\x11': { /* Start output */ continue; }      // CTRL + Q
+		case '\x12': { continue; }                  // IGNORE CTRL + R
+		case '\x13': { /* Stop output */ continue; }       // CTRL + S
+		case '\x14': { /* Swap with prior */ continue; }   // CTRL + T
+		case '\x15': { lineDeleteHome(&l); continue; }     // CTRL + U
+		case '\x16': { /* Insert char code */ continue; }  // CTRL + V
+		case '\x17': { lineDeleteWordHome(&l); continue; } // CTRL + W
+		case '\x18': { continue; }                  // IGNORE CTRL + X
+		case '\x19': { /* Paste deleted */ continue; }     // CTRL + Y
 		case '\x1B': switch ((c = fgetc(stdin))) {
+			case 'b': { lineMoveWordHome(&l); continue; }  // ALT + B
+			case 'd': { lineDeleteWordEnd(&l); continue; } // ALT + D
+			case 'f': { lineMoveWordEnd(&l); continue; }   // ALT + F
 			case '[': switch ((c = fgetc(stdin))) {
-				case '2': switch ((c = fgetc(stdin))) {
-					case '~': { /* TODO */ 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 '1': case '2': case '3': case '4': case '5': case '6':
+				case '7': case '8': case '9': { lineESC(&l, c); continue; }
 				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 '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; }  // BACKSPACE
+		case '\x7F': { lineBackspace(&l); continue; }      // BACKSPACE
 		default: { lineInsert(&l, c); continue; }
 		}
 	}
@@ -133,6 +148,18 @@ ret:;
 	free(l.s); tcrestore(); return r;
 }
 
+/* Handle an extended ^[ sequence */
+static void lineESC(struct line *l, register int c) {
+	switch (c) {
+	case '2': switch ((c = fgetc(stdin))) {
+		case '~': { /* Insert char code */ break; } // INSERT
+	}
+	case '3': switch ((c = fgetc(stdin))) {
+		case '~': { lineDelete(l); break; } // DELETE
+	}
+	}
+}
+
 /* Put stdin into raw mode */
 static inline void tcraw(void) {
 	tcgetattr(STDIN_FILENO, &tco); tcn = tco;
@@ -177,7 +204,21 @@ static void lineMoveRight(struct line *l) {
 	if (l->sp != l->sl) { ++l->sp; fputs("\x1B[C", stdout); } return;
 }
 
-/* Move cursor to the line start */
+/* Move cursor to the word home */
+static void lineMoveWordHome(struct line *l) {
+	for (; l->sp && l->s[l->sp - 1] == ' '; --l->sp);
+	for (; l->sp && l->s[l->sp - 1] != ' '; --l->sp);
+	lineRefresh(l); return;
+}
+
+/* Move cursor to the word end */
+static void lineMoveWordEnd(struct line *l) {
+	for (; l->sp != l->sl && l->s[l->sp] == ' '; ++l->sp);
+	for (; l->sp != l->sl && l->s[l->sp] != ' '; ++l->sp);
+	lineRefresh(l); return;
+}
+
+/* Move cursor to the line home */
 static void lineMoveHome(struct line *l) {
 	l->sp = 0; lineRefresh(l); return;
 }
@@ -217,12 +258,35 @@ static void lineDelete(struct line *l) {
 }
 
 /* Delete the word preceeding the cursor */
-static void lineDeleteWord(struct line *l) {
+static void lineDeleteWordHome(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);
+	l->sl -= p - l->sp; lineRefresh(l); return;
+}
+
+/* Delete the word following the cursor */
+static void lineDeleteWordEnd(struct line *l) {
+	size_t p = l->sp;
+	
+	for (; p != l->sl && l->s[p] == ' '; ++p);
+	for (; p != l->sl && l->s[p] != ' '; ++p);
+	
+	memmove(l->s + l->sp, l->s + p, l->sl - p + 1);
+	l->sl -= p - l->sp; lineRefresh(l); return;
+}
+
+/* Delete characters from cursor to home */
+static void lineDeleteHome(struct line *l) {
+	memmove(l->s, l->s + l->sp, l->sl - l->sp + 1);
+	l->sl -= l->sp; l->sp = 0; lineRefresh(l); return;
+	
+}
+
+/* Delete characters from cursor to end */
+static void lineDeleteEnd(struct line *l) {
+	l->s[(l->sl = l->sp)] = 0; lineRefresh(l); return;
 }