ESH

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

AuthorJamozed <[email protected]>
Date2021-04-01 02:07:48
Commitf83cfdddd3ea35c0d545eae1373c889fb85d21ac
Parentebc6a6fa1b0fa9db350cf5605951cdc3945a1e11

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 */