shithub: femtolisp

Download patch

ref: 29a839ab377965ac0518cb762bad94aa8843bd2f
parent: ad2da48df5d11cc7b31f01a507cdc61a3ed80070
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sun Nov 3 18:20:25 EST 2024

add terminal-{show,hide}-cursor

--- a/terminal_posix.c
+++ b/terminal_posix.c
@@ -4,18 +4,27 @@
 #include <termios.h>
 
 static bool inraw = false;
+static bool cursorvisible = true;
 static bool atexitset = false;
 static struct termios tios;
 
-static void termresetraw(void);
+static void termreset(void);
 
 static int
-termsetraw(bool raw)
+termsetraw(bool raw, bool showcursor)
 {
 	if(!atexitset){
-		atexit(termresetraw);
+		atexit(termreset);
 		atexitset = true;
 	}
+	if(showcursor && !cursorvisible){
+		write(STDOUT_FILENO, "\x1b[?25h", 6);
+		cursorvisible = true;
+	}else if(!showcursor && cursorvisible){
+		write(STDOUT_FILENO, "\x1b[?25l", 6);
+		cursorvisible = false;
+	}
+
 	if(raw && !inraw){
 		if(tcgetattr(STDIN_FILENO, &tios) < 0)
 			return -1;
@@ -24,7 +33,7 @@
 		t.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
 		t.c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN);
 		t.c_oflag &= ~(OPOST);
-		t.c_cc[VMIN] = 1;
+		t.c_cc[VMIN] = 0;
 		if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &t) < 0)
 			return -1;
 		inraw = true;
@@ -37,9 +46,9 @@
 }
 
 static void
-termresetraw(void)
+termreset(void)
 {
-	termsetraw(false);
+	termsetraw(false, true);
 }
 
 BUILTIN("terminal-enter-raw-mode", terminal_enter_raw_mode)
@@ -46,7 +55,7 @@
 {
 	USED(args);
 	argcount(nargs, 0);
-	return termsetraw(true) == 0 ? FL_T : FL_F;
+	return termsetraw(true, cursorvisible) == 0 ? FL_T : FL_F;
 }
 
 BUILTIN("terminal-leave-raw-mode", terminal_leave_raw_mode)
@@ -53,9 +62,23 @@
 {
 	USED(args);
 	argcount(nargs, 0);
-	return termsetraw(false) == 0 ? FL_T : FL_F;
+	return termsetraw(false, cursorvisible) == 0 ? FL_T : FL_F;
 }
 
+BUILTIN("terminal-show-cursor", terminal_show_cursor)
+{
+	USED(args);
+	argcount(nargs, 0);
+	return termsetraw(inraw, true) == 0 ? FL_T : FL_F;
+}
+
+BUILTIN("terminal-hide-cursor", terminal_hide_cursor)
+{
+	USED(args);
+	argcount(nargs, 0);
+	return termsetraw(inraw, false) == 0 ? FL_T : FL_F;
+}
+
 BUILTIN("terminal-get-size", terminal_get_size)
 {
 	USED(args);
@@ -69,7 +92,7 @@
 	cdr_(tex) = mk_cons(); car_(cdr_(tex)) = fixnum(s.ws_row); cdr_(cdr_(tex)) = NIL;
 	int x = s.ws_xpixel, y = s.ws_ypixel;
 	bool wasraw = inraw;
-	if((x == 0 || y == 0) && isatty(STDOUT_FILENO) && termsetraw(true) == 0){
+	if((x == 0 || y == 0) && isatty(STDOUT_FILENO) && termsetraw(true, cursorvisible) == 0){
 		// FIXME(sigrid): read everything out of stdin first
 		write(STDOUT_FILENO, "\x1b[14t", 5);
 		/* make sure not to hang if nothing is returned */
@@ -99,7 +122,7 @@
 			}
 		}
 		if(!wasraw)
-			termsetraw(false);
+			termsetraw(false, cursorvisible);
 	}
 	cdr_(v) = pix = mk_cons(); cdr_(pix) = NIL;
 	car_(pix) = mk_cons(); pix = car_(pix);