-
-
Save jtriley/1108174 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python | |
import os | |
import shlex | |
import struct | |
import platform | |
import subprocess | |
def get_terminal_size(): | |
""" getTerminalSize() | |
- get width and height of console | |
- works on linux,os x,windows,cygwin(windows) | |
originally retrieved from: | |
http://stackoverflow.com/questions/566746/how-to-get-console-window-width-in-python | |
""" | |
current_os = platform.system() | |
tuple_xy = None | |
if current_os == 'Windows': | |
tuple_xy = _get_terminal_size_windows() | |
if tuple_xy is None: | |
tuple_xy = _get_terminal_size_tput() | |
# needed for window's python in cygwin's xterm! | |
if current_os in ['Linux', 'Darwin'] or current_os.startswith('CYGWIN'): | |
tuple_xy = _get_terminal_size_linux() | |
if tuple_xy is None: | |
print "default" | |
tuple_xy = (80, 25) # default value | |
return tuple_xy | |
def _get_terminal_size_windows(): | |
try: | |
from ctypes import windll, create_string_buffer | |
# stdin handle is -10 | |
# stdout handle is -11 | |
# stderr handle is -12 | |
h = windll.kernel32.GetStdHandle(-12) | |
csbi = create_string_buffer(22) | |
res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi) | |
if res: | |
(bufx, bufy, curx, cury, wattr, | |
left, top, right, bottom, | |
maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw) | |
sizex = right - left + 1 | |
sizey = bottom - top + 1 | |
return sizex, sizey | |
except: | |
pass | |
def _get_terminal_size_tput(): | |
# get terminal width | |
# src: http://stackoverflow.com/questions/263890/how-do-i-find-the-width-height-of-a-terminal-window | |
try: | |
cols = int(subprocess.check_call(shlex.split('tput cols'))) | |
rows = int(subprocess.check_call(shlex.split('tput lines'))) | |
return (cols, rows) | |
except: | |
pass | |
def _get_terminal_size_linux(): | |
def ioctl_GWINSZ(fd): | |
try: | |
import fcntl | |
import termios | |
cr = struct.unpack('hh', | |
fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234')) | |
return cr | |
except: | |
pass | |
cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) | |
if not cr: | |
try: | |
fd = os.open(os.ctermid(), os.O_RDONLY) | |
cr = ioctl_GWINSZ(fd) | |
os.close(fd) | |
except: | |
pass | |
if not cr: | |
try: | |
cr = (os.environ['LINES'], os.environ['COLUMNS']) | |
except: | |
return None | |
return int(cr[1]), int(cr[0]) | |
if __name__ == "__main__": | |
sizex, sizey = get_terminal_size() | |
print 'width =', sizex, 'height =', sizey |
Thank you :) I'm using this for http://mio-lang.org/ as part of it's tab completer function
I thought about using it for some stuff I'm writing it (thanks for providing it btw),
I forked it and added some 'caching' so it does not run all the tests again over and over:
https://gist.github.com/Captank/7912710
It boosts it just a bit, 100k calls of the original get_terminal_size() took ~2.4 seconds, now it's just 1.8 seconds
(I'm not sure if that would be the pythonic way, I've just started learning python :'D)
Nice. License?
@maxbane I'm not sure how a license would work here, it was adapted from the script at http://stackoverflow.com/a/6550596/23998 which was adapted from http://code.activestate.com/recipes/440694-determine-size-of-console-window-on-windows/
Hi jtriley I want to thank you for this script. I do a minor changes to it and using it for my own downloader script which is in github. I want to ask if it's ok for you.
Here is the script.
Great! I'll try to use this in my ffunenga/pipgh repo
Sweet, I'll be using a rendition of this in https://github.com/catb0t/input_constrain
For _get_terminal_size_tput
, the subprocess calls should use subprocess.check_output
, not subprocess.check_call
.
The current code causes the size to be printed to the terminal, but the returned size will be (0,0) (that is, if tput
successfully exits on each call).
Thanks! Super helpful!
Note that there is python standard lib function for this now: os.get_terminal_size()
Thanks @Chronial for pointing this out! I note however that the docs for os.get_terminal_size()
says that shutil.get_terminal_size()
is the high-level call that should normally be used.
If you want to get the terminal size on all OS now you just gotta do :
import os
width, height = os.get_terminal_size()
have a nice day 😃
This works in Windows 8.. Thanks!