terminalwriter: auto-format
This commit is contained in:
parent
276405a039
commit
3014d9a3f7
|
@ -1,15 +1,16 @@
|
||||||
"""
|
"""Helper functions for writing to terminals and files."""
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import unicodedata
|
||||||
|
|
||||||
Helper functions for writing to terminals and files.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
import sys, os, unicodedata
|
|
||||||
import py
|
import py
|
||||||
|
from py.builtin import text, bytes
|
||||||
|
|
||||||
|
# This code was initially copied from py 1.8.1, file _io/terminalwriter.py.
|
||||||
|
|
||||||
py3k = sys.version_info[0] >= 3
|
py3k = sys.version_info[0] >= 3
|
||||||
py33 = sys.version_info >= (3, 3)
|
py33 = sys.version_info >= (3, 3)
|
||||||
from py.builtin import text, bytes
|
|
||||||
|
|
||||||
win32_and_ctypes = False
|
win32_and_ctypes = False
|
||||||
colorama = None
|
colorama = None
|
||||||
|
@ -19,6 +20,7 @@ if sys.platform == "win32":
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
import ctypes
|
import ctypes
|
||||||
|
|
||||||
win32_and_ctypes = True
|
win32_and_ctypes = True
|
||||||
except ImportError:
|
except ImportError:
|
||||||
pass
|
pass
|
||||||
|
@ -27,10 +29,14 @@ if sys.platform == "win32":
|
||||||
def _getdimensions():
|
def _getdimensions():
|
||||||
if py33:
|
if py33:
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
size = shutil.get_terminal_size()
|
size = shutil.get_terminal_size()
|
||||||
return size.lines, size.columns
|
return size.lines, size.columns
|
||||||
else:
|
else:
|
||||||
import termios, fcntl, struct
|
import termios
|
||||||
|
import fcntl
|
||||||
|
import struct
|
||||||
|
|
||||||
call = fcntl.ioctl(1, termios.TIOCGWINSZ, "\000" * 8)
|
call = fcntl.ioctl(1, termios.TIOCGWINSZ, "\000" * 8)
|
||||||
height, width = struct.unpack("hhhh", call)[:2]
|
height, width = struct.unpack("hhhh", call)[:2]
|
||||||
return height, width
|
return height, width
|
||||||
|
@ -50,27 +56,28 @@ def get_terminal_width():
|
||||||
# FALLBACK:
|
# FALLBACK:
|
||||||
# * some exception happened
|
# * some exception happened
|
||||||
# * or this is emacs terminal which reports (0,0)
|
# * or this is emacs terminal which reports (0,0)
|
||||||
width = int(os.environ.get('COLUMNS', 80))
|
width = int(os.environ.get("COLUMNS", 80))
|
||||||
|
|
||||||
# XXX the windows getdimensions may be bogus, let's sanify a bit
|
# XXX the windows getdimensions may be bogus, let's sanify a bit
|
||||||
if width < 40:
|
if width < 40:
|
||||||
width = 80
|
width = 80
|
||||||
return width
|
return width
|
||||||
|
|
||||||
|
|
||||||
terminal_width = get_terminal_width()
|
terminal_width = get_terminal_width()
|
||||||
|
|
||||||
char_width = {
|
char_width = {
|
||||||
'A': 1, # "Ambiguous"
|
"A": 1, # "Ambiguous"
|
||||||
'F': 2, # Fullwidth
|
"F": 2, # Fullwidth
|
||||||
'H': 1, # Halfwidth
|
"H": 1, # Halfwidth
|
||||||
'N': 1, # Neutral
|
"N": 1, # Neutral
|
||||||
'Na': 1, # Narrow
|
"Na": 1, # Narrow
|
||||||
'W': 2, # Wide
|
"W": 2, # Wide
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_line_width(text):
|
def get_line_width(text):
|
||||||
text = unicodedata.normalize('NFC', text)
|
text = unicodedata.normalize("NFC", text)
|
||||||
return sum(char_width.get(unicodedata.east_asian_width(c), 1) for c in text)
|
return sum(char_width.get(unicodedata.east_asian_width(c), 1) for c in text)
|
||||||
|
|
||||||
|
|
||||||
|
@ -82,11 +89,11 @@ def ansi_print(text, esc, file=None, newline=True, flush=False):
|
||||||
if esc and not isinstance(esc, tuple):
|
if esc and not isinstance(esc, tuple):
|
||||||
esc = (esc,)
|
esc = (esc,)
|
||||||
if esc and sys.platform != "win32" and file.isatty():
|
if esc and sys.platform != "win32" and file.isatty():
|
||||||
text = (''.join(['\x1b[%sm' % cod for cod in esc]) +
|
text = (
|
||||||
text +
|
"".join(["\x1b[%sm" % cod for cod in esc]) + text + "\x1b[0m"
|
||||||
'\x1b[0m') # ANSI color code "reset"
|
) # ANSI color code "reset"
|
||||||
if newline:
|
if newline:
|
||||||
text += '\n'
|
text += "\n"
|
||||||
|
|
||||||
if esc and win32_and_ctypes and file.isatty():
|
if esc and win32_and_ctypes and file.isatty():
|
||||||
if 1 in esc:
|
if 1 in esc:
|
||||||
|
@ -94,16 +101,17 @@ def ansi_print(text, esc, file=None, newline=True, flush=False):
|
||||||
esc = tuple([x for x in esc if x != 1])
|
esc = tuple([x for x in esc if x != 1])
|
||||||
else:
|
else:
|
||||||
bold = False
|
bold = False
|
||||||
esctable = {() : FOREGROUND_WHITE, # normal
|
esctable = {
|
||||||
(31,): FOREGROUND_RED, # red
|
(): FOREGROUND_WHITE, # normal
|
||||||
(32,): FOREGROUND_GREEN, # green
|
(31,): FOREGROUND_RED, # red
|
||||||
(33,): FOREGROUND_GREEN|FOREGROUND_RED, # yellow
|
(32,): FOREGROUND_GREEN, # green
|
||||||
(34,): FOREGROUND_BLUE, # blue
|
(33,): FOREGROUND_GREEN | FOREGROUND_RED, # yellow
|
||||||
(35,): FOREGROUND_BLUE|FOREGROUND_RED, # purple
|
(34,): FOREGROUND_BLUE, # blue
|
||||||
(36,): FOREGROUND_BLUE|FOREGROUND_GREEN, # cyan
|
(35,): FOREGROUND_BLUE | FOREGROUND_RED, # purple
|
||||||
(37,): FOREGROUND_WHITE, # white
|
(36,): FOREGROUND_BLUE | FOREGROUND_GREEN, # cyan
|
||||||
(39,): FOREGROUND_WHITE, # reset
|
(37,): FOREGROUND_WHITE, # white
|
||||||
}
|
(39,): FOREGROUND_WHITE, # reset
|
||||||
|
}
|
||||||
attr = esctable.get(esc, FOREGROUND_WHITE)
|
attr = esctable.get(esc, FOREGROUND_WHITE)
|
||||||
if bold:
|
if bold:
|
||||||
attr |= FOREGROUND_INTENSITY
|
attr |= FOREGROUND_INTENSITY
|
||||||
|
@ -114,7 +122,7 @@ def ansi_print(text, esc, file=None, newline=True, flush=False):
|
||||||
else:
|
else:
|
||||||
handle = GetStdHandle(STD_OUTPUT_HANDLE)
|
handle = GetStdHandle(STD_OUTPUT_HANDLE)
|
||||||
oldcolors = GetConsoleInfo(handle).wAttributes
|
oldcolors = GetConsoleInfo(handle).wAttributes
|
||||||
attr |= (oldcolors & 0x0f0)
|
attr |= oldcolors & 0x0F0
|
||||||
SetConsoleTextAttribute(handle, attr)
|
SetConsoleTextAttribute(handle, attr)
|
||||||
while len(text) > 32768:
|
while len(text) > 32768:
|
||||||
file.write(text[:32768])
|
file.write(text[:32768])
|
||||||
|
@ -128,21 +136,43 @@ def ansi_print(text, esc, file=None, newline=True, flush=False):
|
||||||
if flush:
|
if flush:
|
||||||
file.flush()
|
file.flush()
|
||||||
|
|
||||||
|
|
||||||
def should_do_markup(file):
|
def should_do_markup(file):
|
||||||
if os.environ.get('PY_COLORS') == '1':
|
if os.environ.get("PY_COLORS") == "1":
|
||||||
return True
|
return True
|
||||||
if os.environ.get('PY_COLORS') == '0':
|
if os.environ.get("PY_COLORS") == "0":
|
||||||
return False
|
return False
|
||||||
return hasattr(file, 'isatty') and file.isatty() \
|
return (
|
||||||
and os.environ.get('TERM') != 'dumb' \
|
hasattr(file, "isatty")
|
||||||
and not (sys.platform.startswith('java') and os._name == 'nt')
|
and file.isatty()
|
||||||
|
and os.environ.get("TERM") != "dumb"
|
||||||
|
and not (sys.platform.startswith("java") and os._name == "nt")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TerminalWriter(object):
|
class TerminalWriter(object):
|
||||||
_esctable = dict(black=30, red=31, green=32, yellow=33,
|
_esctable = dict(
|
||||||
blue=34, purple=35, cyan=36, white=37,
|
black=30,
|
||||||
Black=40, Red=41, Green=42, Yellow=43,
|
red=31,
|
||||||
Blue=44, Purple=45, Cyan=46, White=47,
|
green=32,
|
||||||
bold=1, light=2, blink=5, invert=7)
|
yellow=33,
|
||||||
|
blue=34,
|
||||||
|
purple=35,
|
||||||
|
cyan=36,
|
||||||
|
white=37,
|
||||||
|
Black=40,
|
||||||
|
Red=41,
|
||||||
|
Green=42,
|
||||||
|
Yellow=43,
|
||||||
|
Blue=44,
|
||||||
|
Purple=45,
|
||||||
|
Cyan=46,
|
||||||
|
White=47,
|
||||||
|
bold=1,
|
||||||
|
light=2,
|
||||||
|
blink=5,
|
||||||
|
invert=7,
|
||||||
|
)
|
||||||
|
|
||||||
# XXX deprecate stringio argument
|
# XXX deprecate stringio argument
|
||||||
def __init__(self, file=None, stringio=False, encoding=None):
|
def __init__(self, file=None, stringio=False, encoding=None):
|
||||||
|
@ -152,11 +182,12 @@ class TerminalWriter(object):
|
||||||
else:
|
else:
|
||||||
from sys import stdout as file
|
from sys import stdout as file
|
||||||
elif py.builtin.callable(file) and not (
|
elif py.builtin.callable(file) and not (
|
||||||
hasattr(file, "write") and hasattr(file, "flush")):
|
hasattr(file, "write") and hasattr(file, "flush")
|
||||||
|
):
|
||||||
file = WriteFile(file, encoding=encoding)
|
file = WriteFile(file, encoding=encoding)
|
||||||
if hasattr(file, "isatty") and file.isatty() and colorama:
|
if hasattr(file, "isatty") and file.isatty() and colorama:
|
||||||
file = colorama.AnsiToWin32(file).stream
|
file = colorama.AnsiToWin32(file).stream
|
||||||
self.encoding = encoding or getattr(file, 'encoding', "utf-8")
|
self.encoding = encoding or getattr(file, "encoding", "utf-8")
|
||||||
self._file = file
|
self._file = file
|
||||||
self.hasmarkup = should_do_markup(file)
|
self.hasmarkup = should_do_markup(file)
|
||||||
self._lastlen = 0
|
self._lastlen = 0
|
||||||
|
@ -165,7 +196,7 @@ class TerminalWriter(object):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def fullwidth(self):
|
def fullwidth(self):
|
||||||
if hasattr(self, '_terminal_width'):
|
if hasattr(self, "_terminal_width"):
|
||||||
return self._terminal_width
|
return self._terminal_width
|
||||||
return get_terminal_width()
|
return get_terminal_width()
|
||||||
|
|
||||||
|
@ -198,15 +229,14 @@ class TerminalWriter(object):
|
||||||
|
|
||||||
def _escaped(self, text, esc):
|
def _escaped(self, text, esc):
|
||||||
if esc and self.hasmarkup:
|
if esc and self.hasmarkup:
|
||||||
text = (''.join(['\x1b[%sm' % cod for cod in esc]) +
|
text = "".join(["\x1b[%sm" % cod for cod in esc]) + text + "\x1b[0m"
|
||||||
text +'\x1b[0m')
|
|
||||||
return text
|
return text
|
||||||
|
|
||||||
def markup(self, text, **kw):
|
def markup(self, text, **kw):
|
||||||
esc = []
|
esc = []
|
||||||
for name in kw:
|
for name in kw:
|
||||||
if name not in self._esctable:
|
if name not in self._esctable:
|
||||||
raise ValueError("unknown markup: %r" %(name,))
|
raise ValueError("unknown markup: %r" % (name,))
|
||||||
if kw[name]:
|
if kw[name]:
|
||||||
esc.append(self._esctable[name])
|
esc.append(self._esctable[name])
|
||||||
return self._escaped(text, tuple(esc))
|
return self._escaped(text, tuple(esc))
|
||||||
|
@ -227,7 +257,7 @@ class TerminalWriter(object):
|
||||||
# i.e. 2 + 2*len(sepchar)*N + len(title) <= fullwidth
|
# i.e. 2 + 2*len(sepchar)*N + len(title) <= fullwidth
|
||||||
# 2*len(sepchar)*N <= fullwidth - len(title) - 2
|
# 2*len(sepchar)*N <= fullwidth - len(title) - 2
|
||||||
# N <= (fullwidth - len(title) - 2) // (2*len(sepchar))
|
# N <= (fullwidth - len(title) - 2) // (2*len(sepchar))
|
||||||
N = max((fullwidth - len(title) - 2) // (2*len(sepchar)), 1)
|
N = max((fullwidth - len(title) - 2) // (2 * len(sepchar)), 1)
|
||||||
fill = sepchar * N
|
fill = sepchar * N
|
||||||
line = "%s %s %s" % (fill, title, fill)
|
line = "%s %s %s" % (fill, title, fill)
|
||||||
else:
|
else:
|
||||||
|
@ -256,10 +286,10 @@ class TerminalWriter(object):
|
||||||
write_out(self._file, markupmsg)
|
write_out(self._file, markupmsg)
|
||||||
|
|
||||||
def _update_chars_on_current_line(self, text_or_bytes):
|
def _update_chars_on_current_line(self, text_or_bytes):
|
||||||
newline = b'\n' if isinstance(text_or_bytes, bytes) else '\n'
|
newline = b"\n" if isinstance(text_or_bytes, bytes) else "\n"
|
||||||
current_line = text_or_bytes.rsplit(newline, 1)[-1]
|
current_line = text_or_bytes.rsplit(newline, 1)[-1]
|
||||||
if isinstance(current_line, bytes):
|
if isinstance(current_line, bytes):
|
||||||
current_line = current_line.decode('utf-8', errors='replace')
|
current_line = current_line.decode("utf-8", errors="replace")
|
||||||
if newline in text_or_bytes:
|
if newline in text_or_bytes:
|
||||||
self._chars_on_current_line = len(current_line)
|
self._chars_on_current_line = len(current_line)
|
||||||
self._width_of_current_line = get_line_width(current_line)
|
self._width_of_current_line = get_line_width(current_line)
|
||||||
|
@ -267,17 +297,17 @@ class TerminalWriter(object):
|
||||||
self._chars_on_current_line += len(current_line)
|
self._chars_on_current_line += len(current_line)
|
||||||
self._width_of_current_line += get_line_width(current_line)
|
self._width_of_current_line += get_line_width(current_line)
|
||||||
|
|
||||||
def line(self, s='', **kw):
|
def line(self, s="", **kw):
|
||||||
self.write(s, **kw)
|
self.write(s, **kw)
|
||||||
self._checkfill(s)
|
self._checkfill(s)
|
||||||
self.write('\n')
|
self.write("\n")
|
||||||
|
|
||||||
def reline(self, line, **kw):
|
def reline(self, line, **kw):
|
||||||
if not self.hasmarkup:
|
if not self.hasmarkup:
|
||||||
raise ValueError("cannot use rewrite-line without terminal")
|
raise ValueError("cannot use rewrite-line without terminal")
|
||||||
self.write(line, **kw)
|
self.write(line, **kw)
|
||||||
self._checkfill(line)
|
self._checkfill(line)
|
||||||
self.write('\r')
|
self.write("\r")
|
||||||
self._lastlen = len(line)
|
self._lastlen = len(line)
|
||||||
|
|
||||||
def _checkfill(self, line):
|
def _checkfill(self, line):
|
||||||
|
@ -285,6 +315,7 @@ class TerminalWriter(object):
|
||||||
if diff2last > 0:
|
if diff2last > 0:
|
||||||
self.write(" " * diff2last)
|
self.write(" " * diff2last)
|
||||||
|
|
||||||
|
|
||||||
class Win32ConsoleWriter(TerminalWriter):
|
class Win32ConsoleWriter(TerminalWriter):
|
||||||
def write(self, msg, **kw):
|
def write(self, msg, **kw):
|
||||||
if msg:
|
if msg:
|
||||||
|
@ -299,17 +330,17 @@ class Win32ConsoleWriter(TerminalWriter):
|
||||||
oldcolors = GetConsoleInfo(handle).wAttributes
|
oldcolors = GetConsoleInfo(handle).wAttributes
|
||||||
default_bg = oldcolors & 0x00F0
|
default_bg = oldcolors & 0x00F0
|
||||||
attr = default_bg
|
attr = default_bg
|
||||||
if kw.pop('bold', False):
|
if kw.pop("bold", False):
|
||||||
attr |= FOREGROUND_INTENSITY
|
attr |= FOREGROUND_INTENSITY
|
||||||
|
|
||||||
if kw.pop('red', False):
|
if kw.pop("red", False):
|
||||||
attr |= FOREGROUND_RED
|
attr |= FOREGROUND_RED
|
||||||
elif kw.pop('blue', False):
|
elif kw.pop("blue", False):
|
||||||
attr |= FOREGROUND_BLUE
|
attr |= FOREGROUND_BLUE
|
||||||
elif kw.pop('green', False):
|
elif kw.pop("green", False):
|
||||||
attr |= FOREGROUND_GREEN
|
attr |= FOREGROUND_GREEN
|
||||||
elif kw.pop('yellow', False):
|
elif kw.pop("yellow", False):
|
||||||
attr |= FOREGROUND_GREEN|FOREGROUND_RED
|
attr |= FOREGROUND_GREEN | FOREGROUND_RED
|
||||||
else:
|
else:
|
||||||
attr |= oldcolors & 0x0007
|
attr |= oldcolors & 0x0007
|
||||||
|
|
||||||
|
@ -318,6 +349,7 @@ class Win32ConsoleWriter(TerminalWriter):
|
||||||
if oldcolors:
|
if oldcolors:
|
||||||
SetConsoleTextAttribute(handle, oldcolors)
|
SetConsoleTextAttribute(handle, oldcolors)
|
||||||
|
|
||||||
|
|
||||||
class WriteFile(object):
|
class WriteFile(object):
|
||||||
def __init__(self, writemethod, encoding=None):
|
def __init__(self, writemethod, encoding=None):
|
||||||
self.encoding = encoding
|
self.encoding = encoding
|
||||||
|
@ -339,39 +371,46 @@ if win32_and_ctypes:
|
||||||
|
|
||||||
# ctypes access to the Windows console
|
# ctypes access to the Windows console
|
||||||
STD_OUTPUT_HANDLE = -11
|
STD_OUTPUT_HANDLE = -11
|
||||||
STD_ERROR_HANDLE = -12
|
STD_ERROR_HANDLE = -12
|
||||||
FOREGROUND_BLACK = 0x0000 # black text
|
FOREGROUND_BLACK = 0x0000 # black text
|
||||||
FOREGROUND_BLUE = 0x0001 # text color contains blue.
|
FOREGROUND_BLUE = 0x0001 # text color contains blue.
|
||||||
FOREGROUND_GREEN = 0x0002 # text color contains green.
|
FOREGROUND_GREEN = 0x0002 # text color contains green.
|
||||||
FOREGROUND_RED = 0x0004 # text color contains red.
|
FOREGROUND_RED = 0x0004 # text color contains red.
|
||||||
FOREGROUND_WHITE = 0x0007
|
FOREGROUND_WHITE = 0x0007
|
||||||
FOREGROUND_INTENSITY = 0x0008 # text color is intensified.
|
FOREGROUND_INTENSITY = 0x0008 # text color is intensified.
|
||||||
BACKGROUND_BLACK = 0x0000 # background color black
|
BACKGROUND_BLACK = 0x0000 # background color black
|
||||||
BACKGROUND_BLUE = 0x0010 # background color contains blue.
|
BACKGROUND_BLUE = 0x0010 # background color contains blue.
|
||||||
BACKGROUND_GREEN = 0x0020 # background color contains green.
|
BACKGROUND_GREEN = 0x0020 # background color contains green.
|
||||||
BACKGROUND_RED = 0x0040 # background color contains red.
|
BACKGROUND_RED = 0x0040 # background color contains red.
|
||||||
BACKGROUND_WHITE = 0x0070
|
BACKGROUND_WHITE = 0x0070
|
||||||
BACKGROUND_INTENSITY = 0x0080 # background color is intensified.
|
BACKGROUND_INTENSITY = 0x0080 # background color is intensified.
|
||||||
|
|
||||||
SHORT = ctypes.c_short
|
SHORT = ctypes.c_short
|
||||||
|
|
||||||
class COORD(ctypes.Structure):
|
class COORD(ctypes.Structure):
|
||||||
_fields_ = [('X', SHORT),
|
_fields_ = [("X", SHORT), ("Y", SHORT)]
|
||||||
('Y', SHORT)]
|
|
||||||
class SMALL_RECT(ctypes.Structure):
|
class SMALL_RECT(ctypes.Structure):
|
||||||
_fields_ = [('Left', SHORT),
|
_fields_ = [
|
||||||
('Top', SHORT),
|
("Left", SHORT),
|
||||||
('Right', SHORT),
|
("Top", SHORT),
|
||||||
('Bottom', SHORT)]
|
("Right", SHORT),
|
||||||
|
("Bottom", SHORT),
|
||||||
|
]
|
||||||
|
|
||||||
class CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
|
class CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
|
||||||
_fields_ = [('dwSize', COORD),
|
_fields_ = [
|
||||||
('dwCursorPosition', COORD),
|
("dwSize", COORD),
|
||||||
('wAttributes', wintypes.WORD),
|
("dwCursorPosition", COORD),
|
||||||
('srWindow', SMALL_RECT),
|
("wAttributes", wintypes.WORD),
|
||||||
('dwMaximumWindowSize', COORD)]
|
("srWindow", SMALL_RECT),
|
||||||
|
("dwMaximumWindowSize", COORD),
|
||||||
|
]
|
||||||
|
|
||||||
_GetStdHandle = ctypes.windll.kernel32.GetStdHandle
|
_GetStdHandle = ctypes.windll.kernel32.GetStdHandle
|
||||||
_GetStdHandle.argtypes = [wintypes.DWORD]
|
_GetStdHandle.argtypes = [wintypes.DWORD]
|
||||||
_GetStdHandle.restype = wintypes.HANDLE
|
_GetStdHandle.restype = wintypes.HANDLE
|
||||||
|
|
||||||
def GetStdHandle(kind):
|
def GetStdHandle(kind):
|
||||||
return _GetStdHandle(kind)
|
return _GetStdHandle(kind)
|
||||||
|
|
||||||
|
@ -379,11 +418,13 @@ if win32_and_ctypes:
|
||||||
SetConsoleTextAttribute.argtypes = [wintypes.HANDLE, wintypes.WORD]
|
SetConsoleTextAttribute.argtypes = [wintypes.HANDLE, wintypes.WORD]
|
||||||
SetConsoleTextAttribute.restype = wintypes.BOOL
|
SetConsoleTextAttribute.restype = wintypes.BOOL
|
||||||
|
|
||||||
_GetConsoleScreenBufferInfo = \
|
_GetConsoleScreenBufferInfo = ctypes.windll.kernel32.GetConsoleScreenBufferInfo
|
||||||
ctypes.windll.kernel32.GetConsoleScreenBufferInfo
|
_GetConsoleScreenBufferInfo.argtypes = [
|
||||||
_GetConsoleScreenBufferInfo.argtypes = [wintypes.HANDLE,
|
wintypes.HANDLE,
|
||||||
ctypes.POINTER(CONSOLE_SCREEN_BUFFER_INFO)]
|
ctypes.POINTER(CONSOLE_SCREEN_BUFFER_INFO),
|
||||||
|
]
|
||||||
_GetConsoleScreenBufferInfo.restype = wintypes.BOOL
|
_GetConsoleScreenBufferInfo.restype = wintypes.BOOL
|
||||||
|
|
||||||
def GetConsoleInfo(handle):
|
def GetConsoleInfo(handle):
|
||||||
info = CONSOLE_SCREEN_BUFFER_INFO()
|
info = CONSOLE_SCREEN_BUFFER_INFO()
|
||||||
_GetConsoleScreenBufferInfo(handle, ctypes.byref(info))
|
_GetConsoleScreenBufferInfo(handle, ctypes.byref(info))
|
||||||
|
@ -396,6 +437,7 @@ if win32_and_ctypes:
|
||||||
# and the ending \n causes an empty line to display.
|
# and the ending \n causes an empty line to display.
|
||||||
return info.dwSize.Y, info.dwSize.X - 1
|
return info.dwSize.Y, info.dwSize.X - 1
|
||||||
|
|
||||||
|
|
||||||
def write_out(fil, msg):
|
def write_out(fil, msg):
|
||||||
# XXX sometimes "msg" is of type bytes, sometimes text which
|
# XXX sometimes "msg" is of type bytes, sometimes text which
|
||||||
# complicates the situation. Should we try to enforce unicode?
|
# complicates the situation. Should we try to enforce unicode?
|
||||||
|
|
Loading…
Reference in New Issue