terminal doesn't use enormous windows module anymore
This commit is contained in:
parent
1b98d32579
commit
d4610d7716
1 changed files with 81 additions and 22 deletions
|
|
@ -17,28 +17,87 @@
|
||||||
import macros
|
import macros
|
||||||
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
import windows, os
|
import winlean, os
|
||||||
|
|
||||||
|
const
|
||||||
|
DUPLICATE_SAME_ACCESS = 2
|
||||||
|
FOREGROUND_BLUE = 1
|
||||||
|
FOREGROUND_GREEN = 2
|
||||||
|
FOREGROUND_RED = 4
|
||||||
|
FOREGROUND_INTENSITY = 8
|
||||||
|
BACKGROUND_BLUE = 16
|
||||||
|
BACKGROUND_GREEN = 32
|
||||||
|
BACKGROUND_RED = 64
|
||||||
|
BACKGROUND_INTENSITY = 128
|
||||||
|
|
||||||
|
type
|
||||||
|
SHORT = int16
|
||||||
|
COORD = object
|
||||||
|
X: SHORT
|
||||||
|
Y: SHORT
|
||||||
|
|
||||||
|
SMALL_RECT = object
|
||||||
|
Left: SHORT
|
||||||
|
Top: SHORT
|
||||||
|
Right: SHORT
|
||||||
|
Bottom: SHORT
|
||||||
|
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO = object
|
||||||
|
dwSize: COORD
|
||||||
|
dwCursorPosition: COORD
|
||||||
|
wAttributes: int16
|
||||||
|
srWindow: SMALL_RECT
|
||||||
|
dwMaximumWindowSize: COORD
|
||||||
|
|
||||||
|
proc duplicateHandle(hSourceProcessHandle: HANDLE, hSourceHandle: HANDLE,
|
||||||
|
hTargetProcessHandle: HANDLE, lpTargetHandle: ptr HANDLE,
|
||||||
|
dwDesiredAccess: DWORD, bInheritHandle: WINBOOL,
|
||||||
|
dwOptions: DWORD): WINBOOL{.stdcall, dynlib: "kernel32",
|
||||||
|
importc: "DuplicateHandle".}
|
||||||
|
proc getCurrentProcess(): HANDLE{.stdcall, dynlib: "kernel32",
|
||||||
|
importc: "GetCurrentProcess".}
|
||||||
|
proc getConsoleScreenBufferInfo(hConsoleOutput: HANDLE,
|
||||||
|
lpConsoleScreenBufferInfo: ptr CONSOLE_SCREEN_BUFFER_INFO): WINBOOL{.stdcall,
|
||||||
|
dynlib: "kernel32", importc: "GetConsoleScreenBufferInfo".}
|
||||||
|
|
||||||
|
proc setConsoleCursorPosition(hConsoleOutput: HANDLE,
|
||||||
|
dwCursorPosition: COORD): WINBOOL{.
|
||||||
|
stdcall, dynlib: "kernel32", importc: "SetConsoleCursorPosition".}
|
||||||
|
|
||||||
|
proc fillConsoleOutputCharacter(hConsoleOutput: Handle, cCharacter: char,
|
||||||
|
nLength: DWORD, dwWriteCoord: Coord,
|
||||||
|
lpNumberOfCharsWritten: ptr DWORD): WINBOOL{.
|
||||||
|
stdcall, dynlib: "kernel32", importc: "FillConsoleOutputCharacterA".}
|
||||||
|
|
||||||
|
proc fillConsoleOutputAttribute(hConsoleOutput: HANDLE, wAttribute: int16,
|
||||||
|
nLength: DWORD, dwWriteCoord: COORD,
|
||||||
|
lpNumberOfAttrsWritten: ptr DWORD): WINBOOL{.
|
||||||
|
stdcall, dynlib: "kernel32", importc: "FillConsoleOutputAttribute".}
|
||||||
|
|
||||||
|
proc setConsoleTextAttribute(hConsoleOutput: HANDLE,
|
||||||
|
wAttributes: int16): WINBOOL{.
|
||||||
|
stdcall, dynlib: "kernel32", importc: "SetConsoleTextAttribute".}
|
||||||
|
|
||||||
var
|
var
|
||||||
conHandle: Handle
|
conHandle: Handle
|
||||||
# = createFile("CONOUT$", GENERIC_WRITE, 0, nil, OPEN_ALWAYS, 0, 0)
|
# = createFile("CONOUT$", GENERIC_WRITE, 0, nil, OPEN_ALWAYS, 0, 0)
|
||||||
|
|
||||||
block:
|
block:
|
||||||
var hTemp = GetStdHandle(STD_OUTPUT_HANDLE)
|
var hTemp = getStdHandle(STD_OUTPUT_HANDLE)
|
||||||
if DuplicateHandle(GetCurrentProcess(), hTemp, GetCurrentProcess(),
|
if duplicateHandle(getCurrentProcess(), hTemp, getCurrentProcess(),
|
||||||
addr(conHandle), 0, 1, DUPLICATE_SAME_ACCESS) == 0:
|
addr(conHandle), 0, 1, DUPLICATE_SAME_ACCESS) == 0:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
|
|
||||||
proc getCursorPos(): tuple [x,y: int] =
|
proc getCursorPos(): tuple [x,y: int] =
|
||||||
var c: CONSOLESCREENBUFFERINFO
|
var c: CONSOLESCREENBUFFERINFO
|
||||||
if GetConsoleScreenBufferInfo(conHandle, addr(c)) == 0:
|
if getConsoleScreenBufferInfo(conHandle, addr(c)) == 0:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
return (int(c.dwCursorPosition.X), int(c.dwCursorPosition.Y))
|
return (int(c.dwCursorPosition.X), int(c.dwCursorPosition.Y))
|
||||||
|
|
||||||
proc getAttributes(): int16 =
|
proc getAttributes(): int16 =
|
||||||
var c: CONSOLESCREENBUFFERINFO
|
var c: CONSOLESCREENBUFFERINFO
|
||||||
# workaround Windows bugs: try several times
|
# workaround Windows bugs: try several times
|
||||||
if GetConsoleScreenBufferInfo(conHandle, addr(c)) != 0:
|
if getConsoleScreenBufferInfo(conHandle, addr(c)) != 0:
|
||||||
return c.wAttributes
|
return c.wAttributes
|
||||||
return 0x70'i16 # ERROR: return white background, black text
|
return 0x70'i16 # ERROR: return white background, black text
|
||||||
|
|
||||||
|
|
@ -67,7 +126,7 @@ proc setCursorPos*(x, y: int) =
|
||||||
var c: COORD
|
var c: COORD
|
||||||
c.X = int16(x)
|
c.X = int16(x)
|
||||||
c.Y = int16(y)
|
c.Y = int16(y)
|
||||||
if SetConsoleCursorPosition(conHandle, c) == 0: raiseOSError(osLastError())
|
if setConsoleCursorPosition(conHandle, c) == 0: raiseOSError(osLastError())
|
||||||
else:
|
else:
|
||||||
stdout.write("\e[" & $y & ';' & $x & 'f')
|
stdout.write("\e[" & $y & ';' & $x & 'f')
|
||||||
|
|
||||||
|
|
@ -77,11 +136,11 @@ proc setCursorXPos*(x: int) =
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
var scrbuf: CONSOLESCREENBUFFERINFO
|
var scrbuf: CONSOLESCREENBUFFERINFO
|
||||||
var hStdout = conHandle
|
var hStdout = conHandle
|
||||||
if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0:
|
if getConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
var origin = scrbuf.dwCursorPosition
|
var origin = scrbuf.dwCursorPosition
|
||||||
origin.X = int16(x)
|
origin.X = int16(x)
|
||||||
if SetConsoleCursorPosition(conHandle, origin) == 0:
|
if setConsoleCursorPosition(conHandle, origin) == 0:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
else:
|
else:
|
||||||
stdout.write("\e[" & $x & 'G')
|
stdout.write("\e[" & $x & 'G')
|
||||||
|
|
@ -93,11 +152,11 @@ when defined(windows):
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
var scrbuf: CONSOLESCREENBUFFERINFO
|
var scrbuf: CONSOLESCREENBUFFERINFO
|
||||||
var hStdout = conHandle
|
var hStdout = conHandle
|
||||||
if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0:
|
if getConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
var origin = scrbuf.dwCursorPosition
|
var origin = scrbuf.dwCursorPosition
|
||||||
origin.Y = int16(y)
|
origin.Y = int16(y)
|
||||||
if SetConsoleCursorPosition(conHandle, origin) == 0:
|
if setConsoleCursorPosition(conHandle, origin) == 0:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
else:
|
else:
|
||||||
discard
|
discard
|
||||||
|
|
@ -175,18 +234,18 @@ proc eraseLine* =
|
||||||
var scrbuf: CONSOLESCREENBUFFERINFO
|
var scrbuf: CONSOLESCREENBUFFERINFO
|
||||||
var numwrote: DWORD
|
var numwrote: DWORD
|
||||||
var hStdout = conHandle
|
var hStdout = conHandle
|
||||||
if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0:
|
if getConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
var origin = scrbuf.dwCursorPosition
|
var origin = scrbuf.dwCursorPosition
|
||||||
origin.X = 0'i16
|
origin.X = 0'i16
|
||||||
if SetConsoleCursorPosition(conHandle, origin) == 0:
|
if setConsoleCursorPosition(conHandle, origin) == 0:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
var ht = scrbuf.dwSize.Y - origin.Y
|
var ht = scrbuf.dwSize.Y - origin.Y
|
||||||
var wt = scrbuf.dwSize.X - origin.X
|
var wt = scrbuf.dwSize.X - origin.X
|
||||||
if FillConsoleOutputCharacter(hStdout,' ', ht*wt,
|
if fillConsoleOutputCharacter(hStdout,' ', ht*wt,
|
||||||
origin, addr(numwrote)) == 0:
|
origin, addr(numwrote)) == 0:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
if FillConsoleOutputAttribute(hStdout, scrbuf.wAttributes, ht * wt,
|
if fillConsoleOutputAttribute(hStdout, scrbuf.wAttributes, ht * wt,
|
||||||
scrbuf.dwCursorPosition, addr(numwrote)) == 0:
|
scrbuf.dwCursorPosition, addr(numwrote)) == 0:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
else:
|
else:
|
||||||
|
|
@ -201,14 +260,14 @@ proc eraseScreen* =
|
||||||
var origin: COORD # is inititalized to 0, 0
|
var origin: COORD # is inititalized to 0, 0
|
||||||
var hStdout = conHandle
|
var hStdout = conHandle
|
||||||
|
|
||||||
if GetConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0:
|
if getConsoleScreenBufferInfo(hStdout, addr(scrbuf)) == 0:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
let numChars = int32(scrbuf.dwSize.X)*int32(scrbuf.dwSize.Y)
|
let numChars = int32(scrbuf.dwSize.X)*int32(scrbuf.dwSize.Y)
|
||||||
|
|
||||||
if FillConsoleOutputCharacter(hStdout, ' ', numChars,
|
if fillConsoleOutputCharacter(hStdout, ' ', numChars,
|
||||||
origin, addr(numwrote)) == 0:
|
origin, addr(numwrote)) == 0:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
if FillConsoleOutputAttribute(hStdout, scrbuf.wAttributes, numChars,
|
if fillConsoleOutputAttribute(hStdout, scrbuf.wAttributes, numChars,
|
||||||
origin, addr(numwrote)) == 0:
|
origin, addr(numwrote)) == 0:
|
||||||
raiseOSError(osLastError())
|
raiseOSError(osLastError())
|
||||||
setCursorXPos(0)
|
setCursorXPos(0)
|
||||||
|
|
@ -219,7 +278,7 @@ proc resetAttributes* {.noconv.} =
|
||||||
## resets all attributes; it is advisable to register this as a quit proc
|
## resets all attributes; it is advisable to register this as a quit proc
|
||||||
## with ``system.addQuitProc(resetAttributes)``.
|
## with ``system.addQuitProc(resetAttributes)``.
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
discard SetConsoleTextAttribute(conHandle, oldAttr)
|
discard setConsoleTextAttribute(conHandle, oldAttr)
|
||||||
else:
|
else:
|
||||||
stdout.write("\e[0m")
|
stdout.write("\e[0m")
|
||||||
|
|
||||||
|
|
@ -249,7 +308,7 @@ proc setStyle*(style: set[Style]) =
|
||||||
if styleBlink in style: a = a or int16(BACKGROUND_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 styleReverse in style: a = a or 0x4000'i16 # COMMON_LVB_REVERSE_VIDEO
|
||||||
if styleUnderscore in style: a = a or 0x8000'i16 # COMMON_LVB_UNDERSCORE
|
if styleUnderscore in style: a = a or 0x8000'i16 # COMMON_LVB_UNDERSCORE
|
||||||
discard SetConsoleTextAttribute(conHandle, a)
|
discard setConsoleTextAttribute(conHandle, a)
|
||||||
else:
|
else:
|
||||||
for s in items(style):
|
for s in items(style):
|
||||||
stdout.write("\e[" & $ord(s) & 'm')
|
stdout.write("\e[" & $ord(s) & 'm')
|
||||||
|
|
@ -260,7 +319,7 @@ proc writeStyled*(txt: string, style: set[Style] = {styleBright}) =
|
||||||
var old = getAttributes()
|
var old = getAttributes()
|
||||||
setStyle(style)
|
setStyle(style)
|
||||||
stdout.write(txt)
|
stdout.write(txt)
|
||||||
discard SetConsoleTextAttribute(conHandle, old)
|
discard setConsoleTextAttribute(conHandle, old)
|
||||||
else:
|
else:
|
||||||
setStyle(style)
|
setStyle(style)
|
||||||
stdout.write(txt)
|
stdout.write(txt)
|
||||||
|
|
@ -309,7 +368,7 @@ proc setForegroundColor*(fg: ForegroundColor, bright=false) =
|
||||||
(FOREGROUND_RED or FOREGROUND_BLUE),
|
(FOREGROUND_RED or FOREGROUND_BLUE),
|
||||||
(FOREGROUND_BLUE or FOREGROUND_GREEN),
|
(FOREGROUND_BLUE or FOREGROUND_GREEN),
|
||||||
(FOREGROUND_BLUE or FOREGROUND_GREEN or FOREGROUND_RED)]
|
(FOREGROUND_BLUE or FOREGROUND_GREEN or FOREGROUND_RED)]
|
||||||
discard SetConsoleTextAttribute(conHandle, toU16(old or lookup[fg]))
|
discard setConsoleTextAttribute(conHandle, toU16(old or lookup[fg]))
|
||||||
else:
|
else:
|
||||||
gFG = ord(fg)
|
gFG = ord(fg)
|
||||||
if bright: inc(gFG, 60)
|
if bright: inc(gFG, 60)
|
||||||
|
|
@ -330,7 +389,7 @@ proc setBackgroundColor*(bg: BackgroundColor, bright=false) =
|
||||||
(BACKGROUND_RED or BACKGROUND_BLUE),
|
(BACKGROUND_RED or BACKGROUND_BLUE),
|
||||||
(BACKGROUND_BLUE or BACKGROUND_GREEN),
|
(BACKGROUND_BLUE or BACKGROUND_GREEN),
|
||||||
(BACKGROUND_BLUE or BACKGROUND_GREEN or BACKGROUND_RED)]
|
(BACKGROUND_BLUE or BACKGROUND_GREEN or BACKGROUND_RED)]
|
||||||
discard SetConsoleTextAttribute(conHandle, toU16(old or lookup[bg]))
|
discard setConsoleTextAttribute(conHandle, toU16(old or lookup[bg]))
|
||||||
else:
|
else:
|
||||||
gBG = ord(bg)
|
gBG = ord(bg)
|
||||||
if bright: inc(gBG, 60)
|
if bright: inc(gBG, 60)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue