145 lines
4 KiB
Python
145 lines
4 KiB
Python
"""
|
|
get_terminal_size() -- return width and height of terminal as a tuple
|
|
|
|
code from:
|
|
http://stackoverflow.com/questions/566746/how-to-get-console- window-width-in-
|
|
python
|
|
|
|
written by
|
|
Harco Kuppens (http://stackoverflow.com/users/825214/harco-kuppens)
|
|
|
|
It is mentioned in the stackoverflow response that this code works
|
|
on linux, os x, windows and cygwin (windows).
|
|
"""
|
|
from __future__ import print_function
|
|
|
|
import os
|
|
import shutil
|
|
from pandas.compat import PY3
|
|
|
|
|
|
__all__ = ['get_terminal_size', 'is_terminal']
|
|
|
|
|
|
def get_terminal_size():
|
|
"""
|
|
Detect terminal size and return tuple = (width, height).
|
|
|
|
Only to be used when running in a terminal. Note that the IPython notebook,
|
|
IPython zmq frontends, or IDLE do not run in a terminal,
|
|
"""
|
|
import platform
|
|
|
|
if PY3:
|
|
return shutil.get_terminal_size()
|
|
|
|
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 == 'Linux' or \
|
|
current_os == 'Darwin' or \
|
|
current_os.startswith('CYGWIN'):
|
|
tuple_xy = _get_terminal_size_linux()
|
|
if tuple_xy is None:
|
|
tuple_xy = (80, 25) # default value
|
|
return tuple_xy
|
|
|
|
|
|
def is_terminal():
|
|
"""
|
|
Detect if Python is running in a terminal.
|
|
|
|
Returns True if Python is running in a terminal or False if not.
|
|
"""
|
|
try:
|
|
ip = get_ipython()
|
|
except NameError: # assume standard Python interpreter in a terminal
|
|
return True
|
|
else:
|
|
if hasattr(ip, 'kernel'): # IPython as a Jupyter kernel
|
|
return False
|
|
else: # IPython in a terminal
|
|
return True
|
|
|
|
|
|
def _get_terminal_size_windows():
|
|
res = None
|
|
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)
|
|
except:
|
|
return None
|
|
if res:
|
|
import struct
|
|
(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
|
|
else:
|
|
return None
|
|
|
|
|
|
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:
|
|
import subprocess
|
|
proc = subprocess.Popen(["tput", "cols"],
|
|
stdin=subprocess.PIPE,
|
|
stdout=subprocess.PIPE)
|
|
output = proc.communicate(input=None)
|
|
cols = int(output[0])
|
|
proc = subprocess.Popen(["tput", "lines"],
|
|
stdin=subprocess.PIPE,
|
|
stdout=subprocess.PIPE)
|
|
output = proc.communicate(input=None)
|
|
rows = int(output[0])
|
|
return (cols, rows)
|
|
except:
|
|
return None
|
|
|
|
|
|
def _get_terminal_size_linux():
|
|
def ioctl_GWINSZ(fd):
|
|
try:
|
|
import fcntl
|
|
import termios
|
|
import struct
|
|
cr = struct.unpack(
|
|
'hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))
|
|
except:
|
|
return None
|
|
return cr
|
|
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 or cr == (0, 0):
|
|
try:
|
|
from os import environ as env
|
|
cr = (env['LINES'], env['COLUMNS'])
|
|
except:
|
|
return None
|
|
return int(cr[1]), int(cr[0])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sizex, sizey = get_terminal_size()
|
|
print('width = {w} height = {h}'.format(w=sizex, h=sizey))
|