Author | Jamozed <[email protected]> |
Date | 2021-03-31 23:37:12 |
Commit | ebc6a6fa1b0fa9db350cf5605951cdc3945a1e11 |
Parent | f98c21adad6f645d5f2cf02a5bf6917c101b749f |
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; }