ESH

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

AuthorJamozed <[email protected]>
Date2021-03-29 11:07:03
Commitc8190010e7d68c517e6d85040f0bcbba4d645252
Parent68c405989acf065a3c85f29df9768c22ef183b45

Handle CTRL+L clearscreen in lineread

Diffstat

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

1 files changed, 21 insertions, 4 deletions

diff --git a/src/lineread.c b/src/lineread.c
index a0b8f44..77f23e8 100644
--- a/src/lineread.c
+++ b/src/lineread.c
@@ -34,6 +34,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 
 #include "lib/error.h"
 
+#include <sys/ioctl.h>
 #include <termios.h>
 #include <unistd.h>
 
@@ -45,7 +46,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 
 struct line {
 	char *s; size_t sp, sl, sc; size_t hi;
-	char *prompt; size_t pl;
+	char *prompt; size_t pl; size_t cols;
 };
 
 static struct termios tco, tcn;
@@ -54,6 +55,8 @@ static char *lineedit(void);
 
 static inline void tcraw(void);
 static inline void tcrestore(void);
+static size_t getcols(void);
+static void clearscreen(struct line *l);
 
 static void lineRefresh(struct line *l);
 static void lineMoveLeft(struct line *l);
@@ -78,6 +81,7 @@ static char *lineedit(void) {
 	l.sp = 0; l.sl = 0; l.sc = 1024; l.hi = 0;
 	l.prompt = "$ "; l.pl = strlen(l.prompt);
 
+	if (!(l.cols = getcols())) { return NULL; }
 	if (!(l.s = malloc(l.sc * sizeof (*l.s)))) { return NULL; } l.s[0] = 0;
 
 	tcraw(); fputs(l.prompt, stdout);
@@ -93,6 +97,7 @@ static char *lineedit(void) {
 		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; }
@@ -117,7 +122,7 @@ end:;
 static inline void tcraw(void) {
 	tcgetattr(STDIN_FILENO, &tco); tcn = tco;
 	tcn.c_lflag &= ~(ICANON | ECHO);
-	tcsetattr(STDIN_FILENO, TCSANOW, &tcn);
+	tcsetattr(STDIN_FILENO, TCSAFLUSH, &tcn);
 	return;
 }
 
@@ -127,11 +132,23 @@ static inline void tcrestore(void) {
 	return;
 }
 
+/* Get the number of columns in the terminal */
+static size_t getcols(void) {
+	struct winsize ws;
+	if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) == -1) { return 0; }
+	return ws.ws_col;
+}
+
+/* Clear the screen */
+static void clearscreen(struct line *l) {
+	fputs("\x1B[H\x1B[2J", stdout); lineRefresh(l); return;
+}
+
 /* Refresh line */
 static void lineRefresh(struct line *l) {
-	fputs("\r\x1b[0K", stdout);
+	fputs("\r\x1B[0K", stdout);
 	fputs(l->prompt, stdout); fputs(l->s, stdout);
-	fprintf(stdout, "\r\x1b[%zuC", l->pl + l->sp);
+	fprintf(stdout, "\r\x1B[%zuC", l->pl + l->sp);
 	return;
 }