1# -*- coding: utf-8 -*- 2""" 3Terminal size utility 4--------------------- 5""" 6from __future__ import absolute_import, division, print_function 7 8import os 9import platform 10import warnings 11from struct import Struct 12 13 14def get_terminal_size(default=(80, 25)): 15 """ 16 Get width and height of console; works on linux, os x, windows and cygwin 17 18 Adapted from https://gist.github.com/jtriley/1108174 19 Originally from: http://stackoverflow.com/questions/566746/how-to-get-console-window-width-in-python 20 """ 21 current_os = platform.system() 22 if current_os == "Windows": # pragma: no cover 23 size = _get_terminal_size_windows() 24 if not size: 25 # needed for window's python in cygwin's xterm! 26 size = _get_terminal_size_tput() 27 elif current_os in ("Linux", "Darwin", "FreeBSD", "SunOS") or current_os.startswith( 28 "CYGWIN" 29 ): 30 size = _get_terminal_size_linux() 31 32 else: # pragma: no cover 33 warnings.warn( 34 "Plumbum does not know the type of the current OS for term size, defaulting to UNIX" 35 ) 36 size = _get_terminal_size_linux() 37 38 if ( 39 size is None 40 ): # we'll assume the standard 80x25 if for any reason we don't know the terminal size 41 size = default 42 return size 43 44 45def _get_terminal_size_windows(): # pragma: no cover 46 try: 47 from ctypes import create_string_buffer, windll 48 49 STDERR_HANDLE = -12 50 h = windll.kernel32.GetStdHandle(STDERR_HANDLE) 51 csbi_struct = Struct("hhhhHhhhhhh") 52 csbi = create_string_buffer(csbi_struct.size) 53 res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi) 54 if res: 55 _, _, _, _, _, left, top, right, bottom, _, _ = csbi_struct.unpack(csbi.raw) 56 return right - left + 1, bottom - top + 1 57 return None 58 except Exception: 59 return None 60 61 62def _get_terminal_size_tput(): # pragma: no cover 63 # get terminal width 64 # src: http://stackoverflow.com/questions/263890/how-do-i-find-the-width-height-of-a-terminal-window 65 try: 66 tput = local["tput"] 67 cols = int(tput("cols")) 68 rows = int(tput("lines")) 69 return (cols, rows) 70 except Exception: 71 return None 72 73 74def _ioctl_GWINSZ(fd): 75 yx = Struct("hh") 76 try: 77 import fcntl 78 import termios 79 80 return yx.unpack(fcntl.ioctl(fd, termios.TIOCGWINSZ, "1234")) 81 except Exception: 82 return None 83 84 85def _get_terminal_size_linux(): 86 cr = _ioctl_GWINSZ(0) or _ioctl_GWINSZ(1) or _ioctl_GWINSZ(2) 87 if not cr: 88 try: 89 fd = os.open(os.ctermid(), os.O_RDONLY) 90 cr = _ioctl_GWINSZ(fd) 91 os.close(fd) 92 except Exception: 93 pass 94 if not cr: 95 try: 96 cr = (int(os.environ["LINES"]), int(os.environ["COLUMNS"])) 97 except Exception: 98 return None 99 return cr[1], cr[0] 100