ch = Channel(Nil).new
spawn do
loop do
str = STDIN.raw &.read_char
ch.send(nil) if str == 'q'
end
end
ch.receive
How to run:
# execute it in terminal
crystal run ./example.cr
This code spawns new fiber and awaits until user enters a character in the loop. As soon as q is entered loop the program stops.
However, after program is terminated when you enter anything in terminal the characters are not displayed. Terminal window becomes unusable and bust be restarted.
I think I misuse read_char somehow, like after channel unblocked main fiber execution I need to stop reading from STDIN or smth. Will much appreciate an advice how to fix it.
Adding a simple sleep 1 after ch.receive could be a quick fix for this. I’m not sure, though. The filedescriptor should’ve been reset before the message is sent to the channel (and thus before the program terminates). Delaying program exit might help.
However, I would recommend to use a library for proper TTY handling. IO#raw is a not a good tool for that.
There are multiple bindings available for ncurses for example: https://shardbox.org/search?q=ncurses
I haven’t tried any of them, so no recommendation.