commit 0decc56ccae44332966b70594a93d145f42d304e (patch)
parent c031297e8700b6596990c792cf80ab905d54e35d
Author: Alex Karle <alex@alexkarle.com>
Date: Fri, 8 Jan 2021 00:25:43 -0500
Add initial MVP
As shown in the README, this is already quite a flexible tool (by
reading stdin, the content to practice can be easily filtered to
what you'd really like to practice).
The inspiration for this project came to me after a couple days of
battling with the punctuation keys on my new Atreus keyboard.
I started at one point line-by-line copying one file by hand, but
the constant back-and-forth looking between buffers made it slow.
This is a significant improvement... in under 50 lines of Perl :)
Diffstat:
M | README | | | 13 | +++++++++++++ |
A | typist | | | 43 | +++++++++++++++++++++++++++++++++++++++++++ |
2 files changed, 56 insertions(+), 0 deletions(-)
diff --git a/README b/README
@@ -9,3 +9,16 @@ typist (once implemented) will take existing files as arguments,
reduce them to typeable lines, and then time how long it takes to
get it right (and how many tries). It will store stats per line in
its own database, and present stats / repeat failed items.
+
+Current State
+-------------
+I've whipped up the basics. Give it a whirl!
+
+ # practice some Perl
+ $ typist typist # type some Perl
+
+ # practice large shell commands
+ $ grep '.\{25,\}' ~/.bash_history | typist
+
+For added UX, wrap with rlwrap(1) or similar (only works for
+invocations of the form `typist FILE ...`, since it bakes stdin).
diff --git a/typist b/typist
@@ -0,0 +1,43 @@
+#!/usr/bin/env perl
+# typist -- simple typing tutor
+use strict;
+use warnings;
+use List::Util qw(shuffle);
+
+main();
+
+sub main {
+ # Load in lines
+ my @lines;
+ while (my $l = <ARGV>) {
+ chomp $l;
+ $l =~ s/^\s*//;
+ $l =~ s/\s*$//;
+ if ($l) {
+ push(@lines, $l);
+ }
+ }
+ @lines = shuffle @lines;
+
+ # We've now EITHER hit the end of stdin or read in all the files
+ # So we reopen /dev/tty as our user interface
+ open(my $ttyfh, '<', '/dev/tty') or die "unable to open tty: $!";
+ my $trys = 1;
+ while (my $item = shift @lines) {
+ print "$item\n";
+ my $t = time;
+ my $ans = <$ttyfh>;
+ last if !$ans;
+ chomp $ans;
+ if ($ans eq $item) {
+ my $elap = time - $t;
+ my $wpm = scalar(split(' ', $item)) * 60.0 / $elap;
+ printf "Correct! Took %d tries (%d seconds, %d WPM)\n", $trys, $elap, $wpm;
+ $trys = 1;
+ } else {
+ print "Nope! try again...\n";
+ unshift @lines, $item;
+ $trys++;
+ }
+ }
+}