Merge pull request #4403 from miere43/win-getch

Implemented terminal.getch() for Windows
This commit is contained in:
Andreas Rumpf 2016-06-28 18:55:59 +02:00 • committed by GitHub
commit f7f0cff8b3
2 changed files with 35 additions and 12 deletions

View file

@ -493,17 +493,21 @@ template styledEcho*(args: varargs[expr]): expr =
## Echoes styles arguments to stdout using ``styledWriteLine``. ## Echoes styles arguments to stdout using ``styledWriteLine``.
callStyledEcho(args) callStyledEcho(args)
when defined(nimdoc): proc getch*(): char =
proc getch*(): char = ## Read a single character from the terminal, blocking until it is entered.
## Read a single character from the terminal, blocking until it is entered. ## The character is not printed to the terminal.
## The character is not printed to the terminal. This is not available for when defined(windows):
## Windows. let fd = getStdHandle(STD_INPUT_HANDLE)
discard var keyEvent = KEY_EVENT_RECORD()
elif not defined(windows): var numRead: cint
proc getch*(): char = while true:
## Read a single character from the terminal, blocking until it is entered. # Block until character is entered
## The character is not printed to the terminal. This is not available for doAssert(waitForSingleObject(fd, INFINITE) == WAIT_OBJECT_0)
## Windows. doAssert(readConsoleInput(fd, addr(keyEvent), 1, addr(numRead)) != 0)
if numRead == 0 or keyEvent.eventType != 1 or keyEvent.bKeyDown == 0:
continue
return char(keyEvent.uChar)
else:
let fd = getFileHandle(stdin) let fd = getFileHandle(stdin)
var oldMode: Termios var oldMode: Termios
discard fd.tcgetattr(addr oldMode) discard fd.tcgetattr(addr oldMode)

View file

@ -1016,4 +1016,23 @@ proc wsaCloseEvent*(hEvent: Handle): bool
{.stdcall, importc: "WSACloseEvent", dynlib: "ws2_32.dll".} {.stdcall, importc: "WSACloseEvent", dynlib: "ws2_32.dll".}
proc wsaResetEvent*(hEvent: Handle): bool proc wsaResetEvent*(hEvent: Handle): bool
{.stdcall, importc: "WSAResetEvent", dynlib: "ws2_32.dll".} {.stdcall, importc: "WSAResetEvent", dynlib: "ws2_32.dll".}
type
KEY_EVENT_RECORD* {.final, pure.} = object
eventType*: int16
bKeyDown*: WINBOOL
wRepeatCount*: int16
wVirtualKeyCode*: int16
wVirtualScanCode*: int16
uChar*: int16
dwControlKeyState*: DWORD
when defined(useWinAnsi):
proc readConsoleInput*(hConsoleInput: Handle, lpBuffer: pointer, nLength: cint,
lpNumberOfEventsRead: ptr cint): cint
{.stdcall, dynlib: "kernel32", importc: "ReadConsoleInputA".}
else:
proc readConsoleInput*(hConsoleInput: Handle, lpBuffer: pointer, nLength: cint,
lpNumberOfEventsRead: ptr cint): cint
{.stdcall, dynlib: "kernel32", importc: "ReadConsoleInputW".}