diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2016-12-06 08:49:07 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-12-06 08:49:07 +0100 |
commit | 14b9eaee06894f5bf00548117984381d37f16ec7 (patch) | |
tree | 64e6c3c197fce927ac45bf39fbe276753e75e477 /lib | |
parent | 633eb8a1e57de8e11fcde93a5aa133a39174495f (diff) | |
parent | 3fcb8a3246df86be94b94fede6a5d1249ef03bf2 (diff) | |
download | Nim-14b9eaee06894f5bf00548117984381d37f16ec7.tar.gz |
Merge pull request #5078 from johnnovak/terminal-height
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 |