Hi,
Does Nim have already a kind of keyboard events' listener? I'd like to know when a key was pressed and what was the key, so as to program an action for each key, whether it is an alphanumeric letter or other keys like the arrows, Enter, Esc, etc.
Something similar to this task on RosettaCode which hasn't been solved in Nim yet: http://rosettacode.org/wiki/Keyboard_input/Keypress_check
A portable solution is preferable, but a Windows only solution is welcome too.
import terminal
proc getch_nonblock():char =
when defined(windows):
let fd = getStdHandle(STD_INPUT_HANDLE)
var keyEvent = KEY_EVENT_RECORD()
var numRead: cint
doAssert(waitForSingleObject(fd, INFINITE) == WAIT_OBJECT_0)
doAssert(readConsoleInput(fd, addr(keyEvent), 1, addr(numRead)) != 0)
if numRead == 0 or keyEvent.eventType != 1 or keyEvent.bKeyDown == 0:
return '\0'
return char(keyEvent.uChar)
so, this is untested code, i have no idea what i'm doing, i don't work on windows, i just edited what i found in terminal.nim but maybe it'll give you somewhere to start, since there're no other responses.
don't have a posix solution yet, maybe using async instead of the blocking readChar
I was going to check if @shirleyquirk version worked on windows and try to port Python example from rosetta code to nim... but then I realized that illwill possibly provides the functionality you are looking for and more:
Adapted from illwil readme, works on windows but should be cross platform:
import os, illwill
illwillInit()
while true:
var key = getKey()
case key
of Key.None: discard
of Key.Escape, Key.Q:
break
else:
echo "Key pressed: ", $key
sleep(20)
I am not sure what does illwillInit() does...
Additional note: I also ran in this option for windows (have not tested):
proc getch(): cint {.importc: "_getch", dynlib: "msvcrt.dll".}
illwill is brilliant! you should submit that snippet to rosetta, i'd only set it to not fullscreen:
illwillIInit(fullscreen=false)