From 64dd3eb9c1ac0358e0be3ce037c73e83d4b947c8 Mon Sep 17 00:00:00 2001 From: John Novak Date: Sat, 26 Nov 2016 16:36:08 +1000 Subject: [PATCH 1/4] Fix setStyle for Windows * setStyle did not take the current color flags into account on Windows, this is fixed now * refactoring to get rid of magic constants --- lib/pure/terminal.nim | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim index d4734c3e37..e4c42310a8 100644 --- a/lib/pure/terminal.nim +++ b/lib/pure/terminal.nim @@ -29,6 +29,8 @@ when defined(windows): BACKGROUND_GREEN = 32 BACKGROUND_RED = 64 BACKGROUND_INTENSITY = 128 + FOREGROUND_RGB = FOREGROUND_RED or FOREGROUND_GREEN or FOREGROUND_BLUE + BACKGROUND_RGB = BACKGROUND_RED or BACKGROUND_GREEN or BACKGROUND_BLUE type SHORT = int16 @@ -369,12 +371,13 @@ proc setStyle*(f: File, style: set[Style]) = ## Sets the terminal style. when defined(windows): let h = conHandle(f) + var old = getAttributes(h) and (FOREGROUND_RGB or BACKGROUND_RGB) var a = 0'i16 if styleBright in style: a = a or int16(FOREGROUND_INTENSITY) if styleBlink in style: a = a or int16(BACKGROUND_INTENSITY) if styleReverse in style: a = a or 0x4000'i16 # COMMON_LVB_REVERSE_VIDEO if styleUnderscore in style: a = a or 0x8000'i16 # COMMON_LVB_UNDERSCORE - discard setConsoleTextAttribute(h, a) + discard setConsoleTextAttribute(h, old or a) else: for s in items(style): f.write("\e[" & $ord(s) & 'm') @@ -423,7 +426,7 @@ proc setForegroundColor*(f: File, fg: ForegroundColor, bright=false) = ## Sets the terminal's foreground color. when defined(windows): let h = conHandle(f) - var old = getAttributes(h) and not 0x0007 + var old = getAttributes(h) and not FOREGROUND_RGB if bright: old = old or FOREGROUND_INTENSITY const lookup: array[ForegroundColor, int] = [ @@ -445,7 +448,7 @@ proc setBackgroundColor*(f: File, bg: BackgroundColor, bright=false) = ## Sets the terminal's background color. when defined(windows): let h = conHandle(f) - var old = getAttributes(h) and not 0x0070 + var old = getAttributes(h) and not BACKGROUND_RGB if bright: old = old or BACKGROUND_INTENSITY const lookup: array[BackgroundColor, int] = [ From 88e01ffd925d7f1180d9e95cc59a5ff001299489 Mon Sep 17 00:00:00 2001 From: John Novak Date: Sat, 26 Nov 2016 21:05:50 +1000 Subject: [PATCH 2/4] 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 d4734c3e37..0a2c92bbf3 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 3/4] 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 94c9757a73..08506b6d31 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 -------------- From 95682cdfb7596466a30e610c01bd0c8fad39e877 Mon Sep 17 00:00:00 2001 From: Samadi van Koten Date: Mon, 28 Nov 2016 23:02:30 +0000 Subject: [PATCH 4/4] Remove docgen.nim's dependency on things being in path compiler/docgen.nim relied heavily on $lib/packages/docutils being in path at compile-time. While this works fine when building Nim itself, things start breaking when using compiler as a nimble package. --- compiler/docgen.nim | 6 ++++-- compiler/nim.cfg | 2 -- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/docgen.nim b/compiler/docgen.nim index 76b36d7962..2115449249 100644 --- a/compiler/docgen.nim +++ b/compiler/docgen.nim @@ -13,8 +13,10 @@ import ast, strutils, strtabs, options, msgs, os, ropes, idents, - wordrecg, syntaxes, renderer, lexer, rstast, rst, rstgen, times, highlite, - importer, sempass2, json, xmltree, cgi, typesrenderer, astalgo + wordrecg, syntaxes, renderer, lexer, packages/docutils/rstast, + packages/docutils/rst, packages/docutils/rstgen, times, + packages/docutils/highlite, importer, sempass2, json, xmltree, cgi, + typesrenderer, astalgo type TSections = array[TSymKind, Rope] diff --git a/compiler/nim.cfg b/compiler/nim.cfg index 0ff128ba3c..853ae7e00d 100644 --- a/compiler/nim.cfg +++ b/compiler/nim.cfg @@ -4,8 +4,6 @@ hint[XDeclaredButNotUsed]:off path:"llvm" path:"$projectPath/.." -path:"$lib/packages/docutils" - define:booting #import:"$projectpath/testability"