Author | Jamozed <[email protected]> |
Date | 2021-03-30 00:00:30 |
Commit | 826f57a64a662e1df99120bb167f42096d70a104 |
Parent | c8190010e7d68c517e6d85040f0bcbba4d645252 |
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); +}