def get_terminal_size():
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:
try:
cr = (os.env['LINES'], os.env['COLUMNS'])
except:
cr = (25, 80)
return int(cr[1]), int(cr[0])
python类get_terminal_size()的实例源码
def format_article(article, header=None, footer=None, line=False):
content = ''
if header:
content = '{}\n'.format(header)
if line:
content += '{}\n'.format('=' * (get_terminal_size()[0]-1))
content += '{} - {}\nReading Time: {} Mins\nURL: {}\n'.format(
article['id'],
article['title'] if article['title'] else '(No Title)',
article['reading_time'],
article['url']
)
if footer:
content += footer
return content
def say(msg):
"""Print a message.
Unlike print(), this deals with de-denting and wrapping of text to fit
within the width of the terminal.
Paragraphs separated by blank lines in the input will be wrapped
separately.
"""
msg = str(msg)
msg = re.sub(r'^[ \t]*(.*?)[ \t]*$', r'\1', msg, flags=re.M)
width = get_terminal_size()[0]
paragraphs = re.split(r'\n(?:[ \t]*\n)', msg)
formatted = (textwrap.fill(p.strip(), width=width) for p in paragraphs)
print('\n\n'.join(formatted))
def collect_statuses(workspace):
result = list()
repos = workspace.get_repos()
if not repos:
return result
num_repos = len(repos)
max_len = max((len(x.src) for x in repos))
for i, repo, full_path in workspace.enumerate_repos():
ui.info_count(i, num_repos,
"Checking", repo.src.ljust(max_len + 1), end="\r")
status = tsrc.git.get_status(full_path)
result.append((repo.src, status))
terminal_size = shutil.get_terminal_size()
ui.info(" " * terminal_size.columns, end="\r")
return result
def show(args, _config, _extra_args):
"""Show details about an experiment."""
import pickle
import pprint
name = args.name
with shelve.open('.em') as emdb:
if name not in emdb or name == EM_KEY:
return _die(E_NO_EXP.format(name))
for info_name, info_val in sorted(emdb[name].items()):
if isinstance(info_val, datetime.date):
info_val = info_val.ctime()
print(f'{info_name}: {info_val}')
if not args.opts:
return
opts_path = _expath(name, 'run', 'opts.pkl')
with open(opts_path, 'rb') as f_opts:
print('\noptions:')
opts = pickle.load(f_opts)
cols = shutil.get_terminal_size((80, 20)).columns
pprint.pprint(vars(opts), indent=2, compact=True, width=cols)
def columnize(lines, indent=0, pad=2):
term_width = shutil.get_terminal_size((80, 20)).columns
# prints a list of items in a fashion similar to the dir command
# borrowed from https://gist.github.com/critiqjo/2ca84db26daaeb1715e1
n_lines = len(lines)
if n_lines == 0:
return
col_width = max(len(line) for line in lines)
n_cols = int((term_width + pad - indent)/(col_width + pad))
n_cols = min(n_lines, max(1, n_cols))
col_len = int(n_lines/n_cols) + (0 if n_lines % n_cols == 0 else 1)
if (n_cols - 1) * col_len >= n_lines:
n_cols -= 1
cols = [lines[i*col_len : i*col_len + col_len] for i in range(n_cols)]
rows = list(zip(*cols))
rows_missed = zip(*[col[len(rows):] for col in cols[:-1]])
rows.extend(rows_missed)
for row in rows:
yield [" "*indent + (" "*pad).join(line.ljust(col_width) for line in row)]
def __init__(self, output_type="list", initial_len=1, interval=0, force_single_line=False, no_warning=False, sort_key=lambda x:x[0]):
self.sort_key = sort_key
self.no_warning = no_warning
no_warning and print("All reprint warning diabled.")
global is_atty
# reprint does not work in the IDLE terminal, and any other environment that can't get terminal_size
if is_atty and not all(get_terminal_size()):
if not no_warning:
r = input("Fail to get terminal size, we got {}, continue anyway? (y/N)".format(get_terminal_size()))
if not (r and isinstance(r, str) and r.lower()[0] in ['y','t','1']):
sys.exit(0)
is_atty = False
if output_type == "list":
self.warped_obj = output.SignalList(self, [''] * initial_len)
elif output_type == "dict":
self.warped_obj = output.SignalDict(self, {})
self.interval = interval
self.force_single_line = force_single_line
self._last_update = int(time.time()*1000)
def __exit__(self, exc_type, exc_val, exc_tb):
global is_atty
self.refresh(forced=True)
if is_atty:
columns, _ = get_terminal_size()
if self.force_single_line:
print('\n' * len(self.warped_obj), end="")
else:
print('\n' * lines_of_content(self.warped_obj, columns), end="")
global last_output_lines
global overflow_flag
last_output_lines = 0
if overflow_flag:
if not self.no_warning:
print("Detected that the lines of output has been exceeded the height of terminal windows, which \
caused the former output remained and keep adding new lines.")
print("????????, ??????????????, ???????????, ???????????????????")
def test_stty_match(self):
"""Check if stty returns the same results ignoring env
This test will fail if stdin and stdout are connected to
different terminals with different sizes. Nevertheless, such
situations should be pretty rare.
"""
try:
size = subprocess.check_output(['stty', 'size']).decode().split()
except (FileNotFoundError, subprocess.CalledProcessError):
self.skipTest("stty invocation failed")
expected = (int(size[1]), int(size[0])) # reversed order
with support.EnvironmentVarGuard() as env:
del env['LINES']
del env['COLUMNS']
actual = shutil.get_terminal_size()
self.assertEqual(expected, actual)
def test_stty_match(self):
"""Check if stty returns the same results ignoring env
This test will fail if stdin and stdout are connected to
different terminals with different sizes. Nevertheless, such
situations should be pretty rare.
"""
try:
size = subprocess.check_output(['stty', 'size']).decode().split()
except (FileNotFoundError, subprocess.CalledProcessError):
self.skipTest("stty invocation failed")
expected = (int(size[1]), int(size[0])) # reversed order
with support.EnvironmentVarGuard() as env:
del env['LINES']
del env['COLUMNS']
actual = shutil.get_terminal_size()
self.assertEqual(expected, actual)
def update(self, pos, *, force=False):
self._pos = pos
if not self._activated:
return
if not force and time.time() - self._updated < self._update_threshold:
return
percentage = int(pos / self._total * 100)
term_width, _ = shutil.get_terminal_size()
bar_length = max(40, term_width - 1 - self._static_length)
filled_length = max(int(bar_length * pos / self._total), 1)
bar = '=' * (filled_length - 1) + '>' + ' ' * (bar_length - filled_length)
sys.stderr.write(self._fmt.format(
pos=pos, bar=bar, percentage=percentage,
))
self._updated = time.time()
# After calling done(), call activate() to redraw and re-activate the bar.
def test_stty_match(self):
"""Check if stty returns the same results ignoring env
This test will fail if stdin and stdout are connected to
different terminals with different sizes. Nevertheless, such
situations should be pretty rare.
"""
try:
size = subprocess.check_output(['stty', 'size']).decode().split()
except (FileNotFoundError, subprocess.CalledProcessError):
self.skipTest("stty invocation failed")
expected = (int(size[1]), int(size[0])) # reversed order
with support.EnvironmentVarGuard() as env:
del env['LINES']
del env['COLUMNS']
actual = shutil.get_terminal_size()
self.assertEqual(expected, actual)
def run(self, _args: argparse.Namespace) -> None:
text = util.get_data('howto.txt')
width, _height = shutil.get_terminal_size((80, 20))
body = '\n'.join([
'\n'.join(
wrap(
line,
width=width,
break_long_words=False,
replace_whitespace=False))
for line in text.splitlines()
])
print(body)
def show_help(args=[], **options):
"""
help
Prints the synopsis and a list of the most commonly used commands.
"""
help_dict = set_help(cmdlookup)
help_size = len(help_dict)
console_width = terminal_size().columns / 1.1
console_space = (terminal_size().columns - console_width) / 2.3
index = 0
for func_name in sorted(help_dict.keys()):
func_doc = help_dict[func_name]
index += 1
print(func_doc)
if (index < help_size):
print('{:>{}}*{:-<{}}*'.format(' ', console_space, '', console_width)) # make it pretty.
return ''
def write(self, data):
if not data.rstrip("\n"):
return
f = self._file
cols = get_terminal_size().columns
# Clear the last line.
f.write("\r" + " " * (cols-1))
f.flush()
# Return and write the data.
out = "\r" + data
if not out.endswith("\n"):
out += "\n"
f.write(out)
# Write our string.
f.write(self.line + "\r")
f.flush()
def print_fitting(path):
img = Image.open(path)
termsize = shutil.get_terminal_size((9001, 9001))
if args.bilevel:
scale = min(1, termsize[0]/img.size[0], 2*(termsize[1]-2)/(img.size[1]))
newsize = (2*int(scale*img.size[0]), int(scale*img.size[1]))
newimg = img.convert("1").resize(newsize, Image.LANCZOS)
print_image_bl(newimg)
else:
scale = min(1, termsize[0]/img.size[0], 2*(termsize[1]-2)/(img.size[1]))
newsize = (int(scale*img.size[0]), int(scale*img.size[1]))
newimg = img.convert("RGBA").resize(newsize, Image.LANCZOS)
print_image_tc(newimg)
def get_hr():
term_size = shutil.get_terminal_size((80, 25))
hr = '=' * term_size.columns
return hr
def fill(self, string, indent=' ', max_width=72):
"""Wrap string so it fits within at most ``max_width`` columns.
If the terminal is less than ``max_width`` columns, the string
will be filled into that smaller width instead.
"""
if not isinstance(string, str):
string = ' '.join(string)
width = min(max_width, get_terminal_size().columns)
return textwrap.fill(
string, width=width, initial_indent=indent, subsequent_indent=indent,
break_on_hyphens=False)
def exec_command(self, client, command, timeout=None, get_pty=False, environment=None):
channel = client._transport.open_session(timeout=timeout)
if get_pty:
width, height = get_terminal_size()
channel.get_pty(width=width, height=height)
channel.settimeout(timeout)
if environment:
channel.update_environment(environment)
channel.exec_command(command)
return channel
def __init__(self, parent):
self._parent = parent
self.width = shutil.get_terminal_size((80, 20)).columns - 5
def print_icon():
"""
Prints the MUTE Icon according to the width & height
"""
global FIRST_START
if FIRST_START is False:
os.system('clear')
width, height = shutil.get_terminal_size((80, 20))
space = (width - 39) // 2 * ' '
middle = (height - 20) // 2
for _ in range(middle - 10):
print('') # Which is a '\n'
print(space + W + ' ####' + R + '#####' + W + '## ##' + R + '#####' + W + '####')
print(space + R + ' #### ####')
print(space + R + ' ### ###')
print(space + R + ' ## ##')
print(space + R + ' #########')
print(space + R + ' #########')
print(space + R + ' ## ##')
print(space + R + ' ### ###')
print(space + R + ' ###### ######')
print(space + W + '########' + R + '#####' + W + '# #' + R + '#####' + W + '########')
print('\n')
if not height < 31:
space = (width - 37) // 2 * ' '
print(space + R + '## ## ' + W + '## ## ######## ######## ')
print(space + R + '### ### ' + W + '## ## ## ## ')
print(space + R + '#### #### ' + W + '## ## ## ## ')
print(space + R + '## ### ## ' + W + '## ## ## ###### ')
print(space + R + '## ## ' + W + '## ## ## ## ')
print(space + R + '## ## ' + W + '## ## ## ## ')
print(space + R + '## ## ' + W + ' ####### ## ######## ')
space = (width - 32) // 2 * ' '
print('\n' + space + GR + '(C) K4YT3X 2017 (C) fa11en 2017' + W)
FIRST_START = False
def __init__(self, output, columns = None):
super().__init__(output)
if columns is None:
columns, lines = shutil.get_terminal_size((80, 24))
self.columns = columns
self.chars_on_line = 0
self._prefix = ''
self.prefix_printable_length = 0
self.break_regex = re.compile(' ')
def refresh(self, cur_len):
terminal_width = get_terminal_size().columns # ??????
info = "%s '%s'... %.2f%%" % (self.prefix_info,
self.title,
cur_len/self.total * 100)
while len(info) > terminal_width - 20:
self.title = self.title[0:-4] + '...'
info = "%s '%s'... %.2f%%" % (self.prefix_info,
self.title,
cur_len/self.total * 100)
end_str = '\r' if cur_len < self.total else '\n'
print(info, end=end_str)
def count_down(self):
terminal_width = get_terminal_size().columns
for i in range(self.count_time + 1):
info = "%s %ss" % (self.prefix_info, self.count_time - i)
print(' ' * (terminal_width - 5), end='\r')
print(info, end='\r')
sleep(1)
def __init__(self, option_cls):
self.__option_cls = option_cls
self._parser = argparse.ArgumentParser(formatter_class=
lambda prog: argparse.HelpFormatter(prog, width=shutil.get_terminal_size()[0]))
def get_terminal_size(fallback=(80, 24)):
return fallback
def clear_and_output(self):
"""
Clears the terminal up to the right line then outputs the information
of the task.
"""
# See if output is paused
if self.output_paused:
return
# OK, print
with console_lock:
# Get terminal width
terminal_width = shutil.get_terminal_size((80, 20)).columns
# Get the output we need to print
output = list(self.output(terminal_width))
# Scroll the terminal down/up enough for any new lines
needed_lines = len(output)
new_lines = needed_lines - self.cleared_lines
if new_lines > 0:
print("\n" * new_lines, flush=True, end="")
elif new_lines < 0:
print(
(UP_ONE + CLEAR_LINE) * abs(new_lines),
flush=True,
end="",
)
self.cleared_lines = needed_lines
# Move cursor to top of cleared section
print(
(UP_ONE + CLEAR_LINE) * needed_lines,
flush=True,
end="",
)
for line in output:
print(line)
def __init__(self, get, update_channel, **options):
"""Init AutomaBot.
:param get: The Queue reader side.
:param update_channel: The notification channel id
:param **options: Default commands.Bot parameters
"""
super().__init__(**options)
self.get = get
self.update_channel = update_channel
self.terminal_width = shutil.get_terminal_size((80, 20))[0]
def get_terminal_dimensions():
columns, lines = shutil.get_terminal_size()
return lines, columns
def __init__(self, filename=None, timing=False, **kwargs):
cmd.Cmd.__init__(self, **kwargs)
if 'stdin' in kwargs:
cmd.Cmd.use_rawinput = 0
self.real_stdout = self.stdout
self.smart_stdout = SmartFile(self.stdout)
self.stderr = SmartFile(sys.stderr)
self.filename = filename
self.line_num = 0
self.timing = timing
global cur_dir
cur_dir = os.getcwd()
self.prev_dir = cur_dir
self.columns = shutil.get_terminal_size().columns
self.redirect_dev = None
self.redirect_filename = ''
self.redirect_mode = ''
self.quit_when_no_output = False
self.quit_serial_reader = False
readline.set_completer_delims(DELIMS)
self.set_prompt()