diff options
author | John Novak <john@johnnovak.net> | 2016-11-30 21:27:26 +1000 |
---|---|---|
committer | John Novak <john@johnnovak.net> | 2016-11-30 21:29:35 +1000 |
commit | 3fcb8a3246df86be94b94fede6a5d1249ef03bf2 (patch) | |
tree | 19f132472320a47b7fea0c927ee74454104abc14 /lib | |
parent | b1b2dd606ba736775868853657e331f287423dee (diff) | |
download | Nim-3fcb8a3246df86be94b94fede6a5d1249ef03bf2.tar.gz |
Add terminalHeight, terminalHeightIoctl & terminalSize
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pure/terminal.nim | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/lib/pure/terminal.nim b/lib/pure/terminal.nim index 16cf91d40..7a8113b2a 100644 --- a/lib/pure/terminal.nim +++ b/lib/pure/terminal.nim @@ -83,6 +83,13 @@ when defined(windows): return int(csbi.srWindow.Right - csbi.srWindow.Left + 1) return 0 + proc terminalHeightIoctl*(handles: openArray[Handle]): int = + var csbi: CONSOLE_SCREEN_BUFFER_INFO + for h in handles: + if getConsoleScreenBufferInfo(h, addr csbi) != 0: + return int(csbi.srWindow.Bottom - csbi.srWindow.Top + 1) + return 0 + proc terminalWidth*(): int = var w: int = 0 w = terminalWidthIoctl([ getStdHandle(STD_INPUT_HANDLE), @@ -91,6 +98,14 @@ when defined(windows): if w > 0: return w return 80 + proc terminalHeight*(): int = + var h: int = 0 + h = terminalHeightIoctl([ getStdHandle(STD_INPUT_HANDLE), + getStdHandle(STD_OUTPUT_HANDLE), + getStdHandle(STD_ERROR_HANDLE) ] ) + if h > 0: return h + return 0 + proc setConsoleCursorPosition(hConsoleOutput: HANDLE, dwCursorPosition: COORD): WINBOOL{. stdcall, dynlib: "kernel32", importc: "SetConsoleCursorPosition".} @@ -177,7 +192,17 @@ else: return int(win.ws_col) return 0 + proc terminalHeightIoctl*(fds: openArray[int]): int = + ## Returns terminal height from first fd that supports the ioctl. + + var win: IOctl_WinSize + for fd in fds: + if ioctl(cint(fd), TIOCGWINSZ, addr win) != -1: + return int(win.ws_row) + return 0 + var L_ctermid{.importc, header: "<stdio.h>".}: cint + proc terminalWidth*(): int = ## Returns some reasonable terminal width from either standard file ## descriptors, controlling terminal, environment variables or tradition. @@ -195,6 +220,29 @@ else: return w return 80 #Finally default to venerable value + proc terminalHeight*(): int = + ## Returns some reasonable terminal height from either standard file + ## descriptors, controlling terminal, environment variables or tradition. + ## Zero is returned if the height could not be determined. + + var h = terminalHeightIoctl([0, 1, 2]) # Try standard file descriptors + if h > 0: return h + var cterm = newString(L_ctermid) # Try controlling tty + var fd = open(ctermid(cstring(cterm)), O_RDONLY) + if fd != -1: + h = terminalHeightIoctl([ int(fd) ]) + discard close(fd) + if h > 0: return h + var s = getEnv("LINES") # Try standard env var + if len(s) > 0 and parseInt(string(s), h) > 0 and h > 0: + return h + return 0 # Could not determine height + +proc terminalSize*(): tuple[w, h: int] = + ## Returns the terminal width and height as a tuple. Internally calls + ## `terminalWidth` and `terminalHeight`, so the same assumptions apply. + result = (terminalWidth(), terminalHeight()) + when defined(windows): proc setCursorVisibility(f: File, visible: bool) = var ccsi: CONSOLE_CURSOR_INFO |