summary refs log tree commit diff stats
path: root/lib/pure
diff options
context:
space:
mode:
authormiere43 <x.miere@gmail.com>2016-06-23 23:22:38 +0300
committermiere43 <x.miere@gmail.com>2016-06-23 23:22:38 +0300
commitdd7a24d8ccae7cf943fcb66133c51591fb2e719d (patch)
tree08345aeacb2f41ed07389dacaab9182da80f9cc2 /lib/pure
parent5f4e98bbc7fb8bdd6e60579b26c0001f33ce4f9c (diff)
downloadNim-dd7a24d8ccae7cf943fcb66133c51591fb2e719d.tar.gz
Implemented terminal.getch() for Windows
Diffstat (limited to 'lib/pure')
-rw-r--r--lib/pure/terminal.nim31
1 files changed, 20 insertions, 11 deletions
diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim
index 60f064e7c..60fce04c9 100644
--- a/lib/pure/terminal.nim
+++ b/lib/pure/terminal.nim
@@ -493,17 +493,26 @@ template styledEcho*(args: varargs[expr]): expr =
   ## Echoes styles arguments to stdout using ``styledWriteLine``.
   callStyledEcho(args)
 
-when defined(nimdoc):
-  proc getch*(): char =
-    ## Read a single character from the terminal, blocking until it is entered.
-    ## The character is not printed to the terminal. This is not available for
-    ## Windows.
-    discard
-elif not defined(windows):
-  proc getch*(): char =
-    ## Read a single character from the terminal, blocking until it is entered.
-    ## The character is not printed to the terminal. This is not available for
-    ## Windows.
+proc getch*(): char =
+  ## Read a single character from the terminal, blocking until it is entered.
+  ## The character is not printed to the terminal.
+  when defined(windows):
+    let fd = getStdHandle(STD_INPUT_HANDLE)
+    # Block until character is entered
+    discard waitForSingleObject(fd, INFINITE)
+    var record = INPUT_RECORD()
+    var recordPtr: ptr INPUT_RECORD = addr(record)
+    var numRead: cint 
+    while true:
+      discard readConsoleInput(fd, recordPtr, 1, addr(numRead))
+      if numRead == 0 or record.eventType != 1:
+        continue
+      let keyEvent = cast[ptr KEY_EVENT_RECORD](recordPtr)
+      # skip key release events
+      if keyEvent.bKeyDown == 0:
+        continue
+      return char(keyEvent.UnicodeChar)
+  else:
     let fd = getFileHandle(stdin)
     var oldMode: Termios
     discard fd.tcgetattr(addr oldMode)