Skip to content

Instantly share code, notes, and snippets.

@jkramer
Last active April 26, 2018 15:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jkramer/c47495d8e31da2e1eb3c5f525889d994 to your computer and use it in GitHub Desktop.
Save jkramer/c47495d8e31da2e1eb3c5f525889d994 to your computer and use it in GitHub Desktop.
module Term::ReadKey:ver<0.0.1> {
use Term::termios;
sub read-key(Bool:D :$echo = True --> Str) is export {
my $original-flags := Term::termios.new(:fd($*IN.native-descriptor)).getattr;
# my $flags = $original-flags.clone; # "cloning a CStruct is NYI"
my $flags := Term::termios.new(:fd($*IN.native-descriptor)).getattr;
$flags.unset_lflags('ICANON');
$flags.unset_lflags('ECHO') unless $echo;
$flags.setattr(:NOW);
use NativeCall;
sub getchar() returns int32 is native { * }
my Buf $buf .= new;
my Str $ch;
loop {
given getchar() {
when -1 { return Nil }
default {
$buf.append($_);
CATCH {
default {
# Catch decoding errors and read more bytes until we have a
# complete/valid UTF-8 sequence.
next;
}
}
$ch = $buf.decode;
last;
}
}
}
$original-flags.setattr(:NOW);
return $ch;
}
}
use Term::ReadKey;
say "Press any key.";
my $ch = read-key(:!echo);
say "Excellent choice. ($ch)";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment