Author | Jamozed <[email protected]> |
Date | 2021-04-01 02:07:48 |
Commit | f83cfdddd3ea35c0d545eae1373c889fb85d21ac |
Parent | ebc6a6fa1b0fa9db350cf5605951cdc3945a1e11 |
Improve raw mode handling in lineread
Diffstat
M | CHANGELOG | | | 7 | +++++++ |
M | src/lineread.c | | | 25 | ++++++++++++++++++------- |
2 files changed, 25 insertions, 7 deletions
diff --git a/CHANGELOG b/CHANGELOG index 5973569..ebbfcd9 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,10 @@ +0.3.0, 2021-04-01 +* Greatly expand keycode handling in lineread +* Implement semicolon handling +* Handle CTRL key commands A-B and D-Y +* Handle ALT key commands B, D, and F +* Improve raw mode handling in lineread + 0.2.1, 2021-01-15 * Implement SIGSTOP and SIGQUIT handling * Update buld scripts diff --git a/src/lineread.c b/src/lineread.c index 8e0b1fa..ef4a59d 100644 --- a/src/lineread.c +++ b/src/lineread.c @@ -50,6 +50,7 @@ struct line { }; static struct termios tco, tcn; +static bool atexitset = false; static char *lineedit(void); static void lineESC(struct line *l, register int c); @@ -106,10 +107,10 @@ static char *lineedit(void) { 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 '\x0A': { goto end; } // CTRL + J case '\x0B': { lineDeleteEnd(&l); continue; } // CTRL + K case '\x0C': { clearscreen(&l); continue; } // CTRL + L - case '\x0D': { continue; } // IGNORE CTRL + M + case '\x0D': { goto end; } // ENTER or CTRL + M case '\x0E': { /* Next history */ continue; } // CTRL + N case '\x0F': { goto end; } // CTRL + O case '\x10': { /* Prior history */ continue; } // CTRL + P @@ -135,7 +136,9 @@ static char *lineedit(void) { case 'D': { lineMoveLeft(&l); continue; } // LEFT case 'F': { lineMoveEnd(&l); continue; } // END case 'H': { lineMoveHome(&l); continue; } // HOME + default: { continue; } } + default: { continue; } } case '\x7F': { lineBackspace(&l); continue; } // BACKSPACE default: { lineInsert(&l, c); continue; } @@ -163,15 +166,23 @@ static void lineESC(struct line *l, register int c) { /* Put stdin into raw mode */ static inline void tcraw(void) { tcgetattr(STDIN_FILENO, &tco); tcn = tco; - tcn.c_lflag &= ~(ICANON | ECHO); - tcsetattr(STDIN_FILENO, TCSAFLUSH, &tcn); - return; + if (!atexitset) { atexit(tcrestore); atexitset = true; } + + /* No break, no CR to NL, no parity check, no strip bit, no flow control */ + tcn.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); + /* No post process, 8-bit chars */ + tcn.c_oflag &= ~(OPOST); tcn.c_cflag |= (CS8); + /* Canonical off, echo off, no extensions, no signal characters */ + tcn.c_lflag &= ~(ICANON | ECHO | IEXTEN | ISIG); + /* Read every byte with no delay */ + tcn.c_cc[VMIN] = 1; tcn.c_cc[VTIME] = 0; + + tcsetattr(STDIN_FILENO, TCSAFLUSH, &tcn); return; } /* Restore stdin to canonical mode */ static inline void tcrestore(void) { - tcsetattr(STDIN_FILENO, TCSAFLUSH, &tco); - return; + tcsetattr(STDIN_FILENO, TCSAFLUSH, &tco); return; } /* Get the number of columns in the terminal */