Browse code

Increase tty buffer to 16k

This should avoid tearing when displaying many very long results

John Hawthorn authored on 12/07/2025 04:06:17
Showing 1 changed files
... ...
@@ -39,7 +39,7 @@ void tty_init(tty_t *tty, const char *tty_filename) {
39 39
 		exit(EXIT_FAILURE);
40 40
 	}
41 41
 
42
-	if (setvbuf(tty->fout, NULL, _IOFBF, 4096)) {
42
+	if (setvbuf(tty->fout, NULL, _IOFBF, 16384)) {
43 43
 		perror("setvbuf");
44 44
 		exit(EXIT_FAILURE);
45 45
 	}
Browse code

Add extern C

Ben Judd authored on 03/01/2024 16:38:45
Showing 1 changed files
... ...
@@ -1,4 +1,3 @@
1
-#include <stdio.h>
2 1
 #include <unistd.h>
3 2
 #include <fcntl.h>
4 3
 #include <stdlib.h>
Browse code

Add ability to use null as input delimiter.

Update tty to print newline as space
Add tty_putc

Ashkan Kiani authored on 03/05/2019 10:30:13 • John Hawthorn committed on 16/08/2019 08:05:01
Showing 1 changed files
... ...
@@ -184,6 +184,10 @@ void tty_printf(tty_t *tty, const char *fmt, ...) {
184 184
 	va_end(args);
185 185
 }
186 186
 
187
+void tty_putc(tty_t *tty, char c) {
188
+	fputc(c, tty->fout);
189
+}
190
+
187 191
 void tty_flush(tty_t *tty) {
188 192
 	fflush(tty->fout);
189 193
 }
Browse code

Better pselect error handling

John Hawthorn authored on 16/09/2018 01:02:32
Showing 1 changed files
... ...
@@ -7,6 +7,7 @@
7 7
 #include <sys/ioctl.h>
8 8
 #include <sys/select.h>
9 9
 #include <signal.h>
10
+#include <errno.h>
10 11
 
11 12
 #include "tty.h"
12 13
 
... ...
@@ -117,7 +118,12 @@ int tty_input_ready(tty_t *tty, long int timeout, int return_on_signal) {
117 118
 			return_on_signal ? NULL : &mask);
118 119
 
119 120
 	if (err < 0) {
120
-		return 0;
121
+		if (errno == EINTR) {
122
+			return 0;
123
+		} else {
124
+			perror("select");
125
+			exit(EXIT_FAILURE);
126
+		}
121 127
 	} else {
122 128
 		return FD_ISSET(tty->fdin, &readfs);
123 129
 	}
Browse code

Allow -1 timeout to mean infinite

John Hawthorn authored on 16/09/2018 00:15:42
Showing 1 changed files
... ...
@@ -96,7 +96,7 @@ char tty_getchar(tty_t *tty) {
96 96
 	}
97 97
 }
98 98
 
99
-int tty_input_ready(tty_t *tty, unsigned long timeout, int return_on_signal) {
99
+int tty_input_ready(tty_t *tty, long int timeout, int return_on_signal) {
100 100
 	fd_set readfs;
101 101
 	FD_ZERO(&readfs);
102 102
 	FD_SET(tty->fdin, &readfs);
... ...
@@ -108,7 +108,13 @@ int tty_input_ready(tty_t *tty, unsigned long timeout, int return_on_signal) {
108 108
 	if (!return_on_signal)
109 109
 		sigaddset(&mask, SIGWINCH);
110 110
 
111
-	int err = pselect(tty->fdin + 1, &readfs, NULL, NULL, &ts, &mask);
111
+	int err = pselect(
112
+			tty->fdin + 1,
113
+			&readfs,
114
+			NULL,
115
+			NULL,
116
+			timeout < 0 ? NULL : &ts,
117
+			return_on_signal ? NULL : &mask);
112 118
 
113 119
 	if (err < 0) {
114 120
 		return 0;
Browse code

Allow masking signals in tty_input_ready

John Hawthorn authored on 15/09/2018 21:15:28
Showing 1 changed files
... ...
@@ -6,6 +6,7 @@
6 6
 #include <termios.h>
7 7
 #include <sys/ioctl.h>
8 8
 #include <sys/select.h>
9
+#include <signal.h>
9 10
 
10 11
 #include "tty.h"
11 12
 
... ...
@@ -21,6 +22,10 @@ void tty_close(tty_t *tty) {
21 22
 	close(tty->fdin);
22 23
 }
23 24
 
25
+static void handle_sigwinch(int sig){
26
+	(void)sig;
27
+}
28
+
24 29
 void tty_init(tty_t *tty, const char *tty_filename) {
25 30
 	tty->fdin = open(tty_filename, O_RDONLY);
26 31
 	if (tty->fdin < 0) {
... ...
@@ -62,6 +67,8 @@ void tty_init(tty_t *tty, const char *tty_filename) {
62 67
 	tty_getwinsz(tty);
63 68
 
64 69
 	tty_setnormal(tty);
70
+
71
+	signal(SIGWINCH, handle_sigwinch);
65 72
 }
66 73
 
67 74
 void tty_getwinsz(tty_t *tty) {
... ...
@@ -89,14 +96,19 @@ char tty_getchar(tty_t *tty) {
89 96
 	}
90 97
 }
91 98
 
92
-int tty_input_ready(tty_t *tty, unsigned long timeout) {
99
+int tty_input_ready(tty_t *tty, unsigned long timeout, int return_on_signal) {
93 100
 	fd_set readfs;
94 101
 	FD_ZERO(&readfs);
95 102
 	FD_SET(tty->fdin, &readfs);
96 103
 
97 104
 	struct timespec ts = {timeout / 1000, (timeout % 1000) * 1000000};
98 105
 
99
-	int err = pselect(tty->fdin + 1, &readfs, NULL, NULL, &ts, NULL);
106
+	sigset_t mask;
107
+	sigemptyset(&mask);
108
+	if (!return_on_signal)
109
+		sigaddset(&mask, SIGWINCH);
110
+
111
+	int err = pselect(tty->fdin + 1, &readfs, NULL, NULL, &ts, &mask);
100 112
 
101 113
 	if (err < 0) {
102 114
 		return 0;
Browse code

Return 0 on pselect EINTR

John Hawthorn authored on 15/09/2018 21:12:14
Showing 1 changed files
... ...
@@ -96,8 +96,13 @@ int tty_input_ready(tty_t *tty, unsigned long timeout) {
96 96
 
97 97
 	struct timespec ts = {timeout / 1000, (timeout % 1000) * 1000000};
98 98
 
99
-	pselect(tty->fdin + 1, &readfs, NULL, NULL, &ts, NULL);
100
-	return FD_ISSET(tty->fdin, &readfs);
99
+	int err = pselect(tty->fdin + 1, &readfs, NULL, NULL, &ts, NULL);
100
+
101
+	if (err < 0) {
102
+		return 0;
103
+	} else {
104
+		return FD_ISSET(tty->fdin, &readfs);
105
+	}
101 106
 }
102 107
 
103 108
 static void tty_sgr(tty_t *tty, int code) {
Browse code

Switch to pselect

John Hawthorn authored on 15/09/2018 21:11:02
Showing 1 changed files
... ...
@@ -91,10 +91,12 @@ char tty_getchar(tty_t *tty) {
91 91
 
92 92
 int tty_input_ready(tty_t *tty, unsigned long timeout) {
93 93
 	fd_set readfs;
94
-	struct timeval tv = {timeout / 1000, (timeout % 1000) * 1000};
95 94
 	FD_ZERO(&readfs);
96 95
 	FD_SET(tty->fdin, &readfs);
97
-	select(tty->fdin + 1, &readfs, NULL, NULL, &tv);
96
+
97
+	struct timespec ts = {timeout / 1000, (timeout % 1000) * 1000000};
98
+
99
+	pselect(tty->fdin + 1, &readfs, NULL, NULL, &ts, NULL);
98 100
 	return FD_ISSET(tty->fdin, &readfs);
99 101
 }
100 102
 
Browse code

Pass a timeout to tty_input_ready

John Hawthorn authored on 15/09/2018 20:55:10
Showing 1 changed files
... ...
@@ -89,9 +89,9 @@ char tty_getchar(tty_t *tty) {
89 89
 	}
90 90
 }
91 91
 
92
-int tty_input_ready(tty_t *tty, int pending) {
92
+int tty_input_ready(tty_t *tty, unsigned long timeout) {
93 93
 	fd_set readfs;
94
-	struct timeval tv = {0, pending ? (KEYTIMEOUT * 1000) : 0};
94
+	struct timeval tv = {timeout / 1000, (timeout % 1000) * 1000};
95 95
 	FD_ZERO(&readfs);
96 96
 	FD_SET(tty->fdin, &readfs);
97 97
 	select(tty->fdin + 1, &readfs, NULL, NULL, &tv);
Browse code

Reduce ambiguous char wait time to 25ms

John Hawthorn authored on 10/09/2018 03:53:50
Showing 1 changed files
... ...
@@ -9,6 +9,8 @@
9 9
 
10 10
 #include "tty.h"
11 11
 
12
+#include "../config.h"
13
+
12 14
 void tty_reset(tty_t *tty) {
13 15
 	tcsetattr(tty->fdin, TCSANOW, &tty->original_termios);
14 16
 }
... ...
@@ -89,7 +91,7 @@ char tty_getchar(tty_t *tty) {
89 91
 
90 92
 int tty_input_ready(tty_t *tty, int pending) {
91 93
 	fd_set readfs;
92
-	struct timeval tv = {0, pending ? 500000 : 0};
94
+	struct timeval tv = {0, pending ? (KEYTIMEOUT * 1000) : 0};
93 95
 	FD_ZERO(&readfs);
94 96
 	FD_SET(tty->fdin, &readfs);
95 97
 	select(tty->fdin + 1, &readfs, NULL, NULL, &tv);
Browse code

Merge branch 'abort_on_escape'

John Hawthorn authored on 10/09/2018 04:02:45
Showing 0 changed files
Browse code

Add sequence to disable line wrap

John Hawthorn authored on 09/09/2018 19:53:08
Showing 1 changed files
... ...
@@ -119,6 +119,14 @@ void tty_setnormal(tty_t *tty) {
119 119
 	tty->fgcolor = 9;
120 120
 }
121 121
 
122
+void tty_setnowrap(tty_t *tty) {
123
+	tty_printf(tty, "%c%c?7l", 0x1b, '[');
124
+}
125
+
126
+void tty_setwrap(tty_t *tty) {
127
+	tty_printf(tty, "%c%c?7h", 0x1b, '[');
128
+}
129
+
122 130
 void tty_newline(tty_t *tty) {
123 131
 	tty_printf(tty, "%c%cK\n", 0x1b, '[');
124 132
 }
Browse code

Add support for underlining selected item

Michael Mackus authored on 18/07/2018 21:54:22
Showing 1 changed files
... ...
@@ -110,6 +110,10 @@ void tty_setinvert(tty_t *tty) {
110 110
 	tty_sgr(tty, 7);
111 111
 }
112 112
 
113
+void tty_setunderline(tty_t *tty) {
114
+	tty_sgr(tty, 4);
115
+}
116
+
113 117
 void tty_setnormal(tty_t *tty) {
114 118
 	tty_sgr(tty, 0);
115 119
 	tty->fgcolor = 9;
Browse code

Abort if Esc is pressed

Jason Felice authored on 04/05/2018 16:32:40
Showing 1 changed files
... ...
@@ -87,9 +87,9 @@ char tty_getchar(tty_t *tty) {
87 87
 	}
88 88
 }
89 89
 
90
-int tty_input_ready(tty_t *tty) {
90
+int tty_input_ready(tty_t *tty, int pending) {
91 91
 	fd_set readfs;
92
-	struct timeval tv = {0, 0};
92
+	struct timeval tv = {0, pending ? 500000 : 0};
93 93
 	FD_ZERO(&readfs);
94 94
 	FD_SET(tty->fdin, &readfs);
95 95
 	select(tty->fdin + 1, &readfs, NULL, NULL, &tv);
Browse code

Initialize fd_set correctly

Jason Felice authored on 04/05/2018 15:42:34
Showing 1 changed files
... ...
@@ -90,6 +90,7 @@ char tty_getchar(tty_t *tty) {
90 90
 int tty_input_ready(tty_t *tty) {
91 91
 	fd_set readfs;
92 92
 	struct timeval tv = {0, 0};
93
+	FD_ZERO(&readfs);
93 94
 	FD_SET(tty->fdin, &readfs);
94 95
 	select(tty->fdin + 1, &readfs, NULL, NULL, &tv);
95 96
 	return FD_ISSET(tty->fdin, &readfs);
Browse code

Add sys/select.h to fix building with musl libc

Duncaen authored on 30/07/2016 21:11:13 • John Hawthorn committed on 01/08/2016 06:41:16
Showing 1 changed files
... ...
@@ -5,6 +5,7 @@
5 5
 #include <stdarg.h>
6 6
 #include <termios.h>
7 7
 #include <sys/ioctl.h>
8
+#include <sys/select.h>
8 9
 
9 10
 #include "tty.h"
10 11
 
Browse code

Batch together input for searches

John Hawthorn authored on 21/06/2016 06:29:15
Showing 1 changed files
... ...
@@ -86,6 +86,14 @@ char tty_getchar(tty_t *tty) {
86 86
 	}
87 87
 }
88 88
 
89
+int tty_input_ready(tty_t *tty) {
90
+	fd_set readfs;
91
+	struct timeval tv = {0, 0};
92
+	FD_SET(tty->fdin, &readfs);
93
+	select(tty->fdin + 1, &readfs, NULL, NULL, &tv);
94
+	return FD_ISSET(tty->fdin, &readfs);
95
+}
96
+
89 97
 static void tty_sgr(tty_t *tty, int code) {
90 98
 	tty_printf(tty, "%c%c%im", 0x1b, '[', code);
91 99
 }
Browse code

Move sources into src directory

John Hawthorn authored on 21/05/2016 21:56:03
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,142 @@
1
+#include <stdio.h>
2
+#include <unistd.h>
3
+#include <fcntl.h>
4
+#include <stdlib.h>
5
+#include <stdarg.h>
6
+#include <termios.h>
7
+#include <sys/ioctl.h>
8
+
9
+#include "tty.h"
10
+
11
+void tty_reset(tty_t *tty) {
12
+	tcsetattr(tty->fdin, TCSANOW, &tty->original_termios);
13
+}
14
+
15
+void tty_close(tty_t *tty) {
16
+	tty_reset(tty);
17
+	fclose(tty->fout);
18
+	close(tty->fdin);
19
+}
20
+
21
+void tty_init(tty_t *tty, const char *tty_filename) {
22
+	tty->fdin = open(tty_filename, O_RDONLY);
23
+	if (tty->fdin < 0) {
24
+		perror("Failed to open tty");
25
+		exit(EXIT_FAILURE);
26
+	}
27
+
28
+	tty->fout = fopen(tty_filename, "w");
29
+	if (!tty->fout) {
30
+		perror("Failed to open tty");
31
+		exit(EXIT_FAILURE);
32
+	}
33
+
34
+	if (setvbuf(tty->fout, NULL, _IOFBF, 4096)) {
35
+		perror("setvbuf");
36
+		exit(EXIT_FAILURE);
37
+	}
38
+
39
+	if (tcgetattr(tty->fdin, &tty->original_termios)) {
40
+		perror("tcgetattr");
41
+		exit(EXIT_FAILURE);
42
+	}
43
+
44
+	struct termios new_termios = tty->original_termios;
45
+
46
+	/*
47
+	 * Disable all of
48
+	 * ICANON  Canonical input (erase and kill processing).
49
+	 * ECHO    Echo.
50
+	 * ISIG    Signals from control characters
51
+	 * ICRNL   Conversion of CR characters into NL
52
+	 */
53
+	new_termios.c_iflag &= ~(ICRNL);
54
+	new_termios.c_lflag &= ~(ICANON | ECHO | ISIG);
55
+
56
+	if (tcsetattr(tty->fdin, TCSANOW, &new_termios))
57
+		perror("tcsetattr");
58
+
59
+	tty_getwinsz(tty);
60
+
61
+	tty_setnormal(tty);
62
+}
63
+
64
+void tty_getwinsz(tty_t *tty) {
65
+	struct winsize ws;
66
+	if (ioctl(fileno(tty->fout), TIOCGWINSZ, &ws) == -1) {
67
+		tty->maxwidth = 80;
68
+		tty->maxheight = 25;
69
+	} else {
70
+		tty->maxwidth = ws.ws_col;
71
+		tty->maxheight = ws.ws_row;
72
+	}
73
+}
74
+
75
+char tty_getchar(tty_t *tty) {
76
+	char ch;
77
+	int size = read(tty->fdin, &ch, 1);
78
+	if (size < 0) {
79
+		perror("error reading from tty");
80
+		exit(EXIT_FAILURE);
81
+	} else if (size == 0) {
82
+		/* EOF */
83
+		exit(EXIT_FAILURE);
84
+	} else {
85
+		return ch;
86
+	}
87
+}
88
+
89
+static void tty_sgr(tty_t *tty, int code) {
90
+	tty_printf(tty, "%c%c%im", 0x1b, '[', code);
91
+}
92
+
93
+void tty_setfg(tty_t *tty, int fg) {
94
+	if (tty->fgcolor != fg) {
95
+		tty_sgr(tty, 30 + fg);
96
+		tty->fgcolor = fg;
97
+	}
98
+}
99
+
100
+void tty_setinvert(tty_t *tty) {
101
+	tty_sgr(tty, 7);
102
+}
103
+
104
+void tty_setnormal(tty_t *tty) {
105
+	tty_sgr(tty, 0);
106
+	tty->fgcolor = 9;
107
+}
108
+
109
+void tty_newline(tty_t *tty) {
110
+	tty_printf(tty, "%c%cK\n", 0x1b, '[');
111
+}
112
+
113
+void tty_clearline(tty_t *tty) {
114
+	tty_printf(tty, "%c%cK", 0x1b, '[');
115
+}
116
+
117
+void tty_setcol(tty_t *tty, int col) {
118
+	tty_printf(tty, "%c%c%iG", 0x1b, '[', col + 1);
119
+}
120
+
121
+void tty_moveup(tty_t *tty, int i) {
122
+	tty_printf(tty, "%c%c%iA", 0x1b, '[', i);
123
+}
124
+
125
+void tty_printf(tty_t *tty, const char *fmt, ...) {
126
+	va_list args;
127
+	va_start(args, fmt);
128
+	vfprintf(tty->fout, fmt, args);
129
+	va_end(args);
130
+}
131
+
132
+void tty_flush(tty_t *tty) {
133
+	fflush(tty->fout);
134
+}
135
+
136
+size_t tty_getwidth(tty_t *tty) {
137
+	return tty->maxwidth;
138
+}
139
+
140
+size_t tty_getheight(tty_t *tty) {
141
+	return tty->maxheight;
142
+}