From 88e01ffd925d7f1180d9e95cc59a5ff001299489 Mon Sep 17 00:00:00 2001 From: John Novak Date: Sat, 26 Nov 2016 21:05:50 +1000 Subject: [PATCH 1/2] Add hideCursor & showCursor --- lib/pure/terminal.nim | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim index d4734c3e3..0a2c92bbf 100644 --- a/lib/pure/terminal.nim +++ b/lib/pure/terminal.nim @@ -13,6 +13,8 @@ ## Windows API. ## Changing the style is permanent even after program termination! Use the ## code ``system.addQuitProc(resetAttributes)`` to restore the defaults. +## Similarly, if you hide the cursor, make sure to unhide it with +## ``showCursor`` before quitting. import macros @@ -49,6 +51,10 @@ when defined(windows): srWindow: SMALL_RECT dwMaximumWindowSize: COORD + CONSOLE_CURSOR_INFO = object + dwSize: DWORD + bVisible: WINBOOL + proc duplicateHandle(hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE, hTargetProcessHandle: HANDLE, lpTargetHandle: ptr HANDLE, dwDesiredAccess: DWORD, bInheritHandle: WINBOOL, @@ -60,6 +66,14 @@ when defined(windows): lpConsoleScreenBufferInfo: ptr CONSOLE_SCREEN_BUFFER_INFO): WINBOOL{.stdcall, dynlib: "kernel32", importc: "GetConsoleScreenBufferInfo".} + proc getConsoleCursorInfo(hConsoleOutput: HANDLE, + lpConsoleCursorInfo: ptr CONSOLE_CURSOR_INFO): WINBOOL{. + stdcall, dynlib: "kernel32", importc: "GetConsoleCursorInfo".} + + proc setConsoleCursorInfo(hConsoleOutput: HANDLE, + lpConsoleCursorInfo: ptr CONSOLE_CURSOR_INFO): WINBOOL{. + stdcall, dynlib: "kernel32", importc: "SetConsoleCursorInfo".} + proc terminalWidthIoctl*(handles: openArray[Handle]): int = var csbi: CONSOLE_SCREEN_BUFFER_INFO for h in handles: @@ -179,6 +193,30 @@ else: return w return 80 #Finally default to venerable value +when defined(windows): + proc setCursorVisibility(f: File, visible: bool) = + var ccsi: CONSOLE_CURSOR_INFO + let h = conHandle(f) + if getConsoleCursorInfo(h, addr(ccsi)) == 0: + raiseOSError(osLastError()) + ccsi.bVisible = if visible: 1 else: 0 + if setConsoleCursorInfo(h, addr(ccsi)) == 0: + raiseOSError(osLastError()) + +proc hideCursor*(f: File) = + ## Hides the cursor. + when defined(windows): + setCursorVisibility(f, false) + else: + f.write("\e[?25l") + +proc showCursor*(f: File) = + ## Shows the cursor. + when defined(windows): + setCursorVisibility(f, true) + else: + f.write("\e[?25h") + proc setCursorPos*(f: File, x, y: int) = ## Sets the terminal's cursor to the (x,y) position. ## (0,0) is the upper left of the screen. @@ -558,6 +596,8 @@ proc getch*(): char = discard fd.tcsetattr(TCSADRAIN, addr oldMode) # Wrappers assuming output to stdout: +template hideCursor*() = hideCursor(stdout) +template showCursor*() = showCursor(stdout) template setCursorPos*(x, y: int) = setCursorPos(stdout, x, y) template setCursorXPos*(x: int) = setCursorXPos(stdout, x) when defined(windows): From 8378a752678fccecfffaeb94dc6d086e540c50d8 Mon Sep 17 00:00:00 2001 From: John Novak Date: Sun, 27 Nov 2016 20:54:46 +1000 Subject: [PATCH 2/2] Update changelog --- web/news/e029_version_0_16_0.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/news/e029_version_0_16_0.rst b/web/news/e029_version_0_16_0.rst index 94c9757a7..08506b6d3 100644 --- a/web/news/e029_version_0_16_0.rst +++ b/web/news/e029_version_0_16_0.rst @@ -36,6 +36,10 @@ Library Additions - Added new parameter to ``error`` proc of ``macro`` module to provide better error message +- Added ``hideCursor`` and ``showCursor`` to the ``terminal`` + `(doc) `_ module. + + Tool Additions --------------