commit 5a92fc280937a2d6f19a821124736e98f15016af
parent cd78494b61532c846e7ae2f4d9142330160a6560
Author: Louis Burda <quent.burda@gmail.com>
Date: Wed, 18 May 2022 19:32:33 +0200
Minor fixes
Diffstat:
M | .gitignore | | | 1 | + |
M | main.c | | | 57 | ++++++++++++++++++++++++++++++++++++++++----------------- |
2 files changed, 41 insertions(+), 17 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1 +1,2 @@
typetest
+input
diff --git a/main.c b/main.c
@@ -10,9 +10,10 @@
#define LINTERP(a,b,v) ((a) * (v) + (b) * (1 - (v)))
enum {
- C_EOF = 0x03,
- C_EOT = 0x04,
- C_DEL = 0x7f
+ C_EOF = 0x03, /* CTRL+C */
+ C_EOT = 0x04, /* CTRL+D */
+ C_DEL = 0x7f,
+ C_SKIP = 0x17, /* CTRL+W */
};
enum {
@@ -88,33 +89,44 @@ time_sub(struct timespec *new, struct timespec *old)
int
type(const char *text, const char *preview)
{
- char input[1024];
int i, c, right, wrong, tlen;
struct timespec start = { 0 }, end;
float cps;
+ if (typed > 0) clock_gettime(CLOCK_REALTIME, &start);
+
tlen = strlen(text);
c = right = wrong = 0;
- do {
+ while (1) {
printf("\r\x1b[2K"); /* goto beginning of row and clear */
printf("\n\x1b[2K\x1b[1A"); /* down a row and clear */
switch (c) {
case C_EOF:
- case C_EOT:
goto quit;
+ case C_EOT:
+ goto exit;
case C_DEL:
if (wrong) wrong--;
else if (right) right--;
break;
+ case C_SKIP:
+ right += wrong + 1;
+ if (right >= tlen)
+ goto exit;
+ wrong = 0;
+ break;
+ case u'\r':
case u'\n':
case u'\0':
break;
+ case ' ':
+ if (!wrong && right == tlen)
+ goto exit;
default:
if (!start.tv_sec)
clock_gettime(CLOCK_REALTIME, &start);
if (right + wrong == tlen) break;
- if (right + wrong == sizeof(input)) break;
if (c == text[right + wrong] && !wrong) right++;
else wrong++;
break;
@@ -136,20 +148,33 @@ type(const char *text, const char *preview)
if (right + wrong)
printf("\x1b[%iC", right + wrong);
- if (!wrong && right + wrong == tlen) break;
- } while ((c = getchar()) > 0);
+ if (!*preview && !wrong && right == tlen)
+ goto exit;
-quit:
- if (!start.tv_sec || typed + right + wrong < 20) return 1;
+ c = getchar();
+ if (c < 0) goto quit;
+ };
+
+exit:
+ printf("\r\x1b[2K"); /* goto beginning of line and clear */
+ printf("\n\x1b[2K\x1b[1A"); /* down a row and clear */
+
+ if (!start.tv_sec) return 1;
clock_gettime(CLOCK_REALTIME, &end);
time_sub(&end, &start);
- cps = (right + wrong) / (end.tv_sec + end.tv_nsec / 1e9f);
+ typed += right;
+
+ end.tv_nsec /= 1000000; /* reduce precision to millis */
+ cps = right / (end.tv_sec + end.tv_nsec / 1e3f);
if (!typed) gcps = cps;
- else gcps = LINTERP(gcps, cps, typed * 1.f / (typed + right + wrong));
+ else gcps = LINTERP(cps, gcps, right * 1.f / typed);
return 0;
+
+quit:
+ return 1;
}
int
@@ -158,8 +183,7 @@ getl(FILE *f, char *buf, size_t size)
int i;
do {
- if (!fgets(buf, size, f))
- return 1;
+ if (!fgets(buf, size, f)) return 1;
for (i = strlen(buf) - 1; *buf; buf[i--] = '\0')
if (!strchr("\n\r", buf[i])) break;
@@ -177,8 +201,8 @@ reset()
int
main(int argc, const char **argv)
{
- struct termios t;
char cur[256], next[256];
+ struct termios t;
int eof;
FILE *f;
@@ -207,7 +231,6 @@ main(int argc, const char **argv)
if (type(cur, eof ? "" : next)) break;
}
- printf("\r\x1b[2K");
if (gcps) {
printf("CPM: %0.2f\n\r", gcps * 60);
printf("WPM: %0.2f\n\r", gcps * 12);