On 12/22/20, Barry Scott <ba...@barrys-emacs.org> wrote: > > import sys > > def clear_terminal(): > if sys.platform == 'win32': > import ctypes > kernel32 = ctypes.windll.kernel32 > # turn on the console ANSI colour handling > kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7) > > sys.stdout.write('\x1b[2J' '\x1b[H')
Here are some concerns I have: * Does not support Windows 8 * Does not support legacy console in Windows 10 (on the "options" tab) * Does not check for SetConsoleMode failure * Does not support a different active screen buffer * Assumes StandardOutput is a screen buffer for the current console * Assumes the current mode of the screen buffer is 3 or 7. New modes have been added, and even more may be added * Sets a global console setting that persists after Python exits Like the CRT's "conio" API, clear_screen() should open "conout$" (temporarily), which will succeed if Python is attached to a console, regardless of the state of the standard handles, file descriptors, or sys.stdout, and will always open the currently active screen buffer, regardless of how many screen buffers exist in the current console session. The current mode should be queried for ENABLE_VIRTUAL_TERMINAL_PROCESSING (4) via GetConsoleMode(). If it's not enabled, bitwise OR it into the mode and try to enable it via SetConsoleMode(). If VT mode is enabled, write '\x1b[2J\x1b[H' to the file. If VT mode can't be enabled, then fall back on the legacy console API. In particular, some people mentioned not wanting to spawn a cmd.exe process just to use its CLS command. Even if spawning a process is okay, the CLS command clears the scrollback, which is inconsistent with ESC[2J. If clear_screen() is going to add ESC[3J to clear the scrollback, then it's at least consistent, but I'd rather not clear the scrollback. clear_screen() should be able to emulate ESC[2J via GetConsoleScreenBufferInfoEx (get the screen buffer size, window, cursor position, and default character attributes), ScrollConsoleScreenBuffer (if the screen buffer has to be scrolled up to make space), and SetConsoleScreenBufferInfoEx (shift the visible window in the buffer and set the cursor position). This can be implemented in ctypes or C. But normally the standard library avoids using ctypes. Finally, if VT mode was temporarily enabled, revert to the original mode, and always close the "conout$" file. Off topic comment: > kernel32 = ctypes.windll.kernel32 I recommend the following instead: kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) The global library loaders such as ctypes.cdll and ctypes.windll are not reliable for production code in the wild. They cache CDLL library instances, which cache function pointers, which may have argtypes, restype, and errcheck prototypes. Another imported package might set function prototypes that break your code, which is an actual problem that I've seen a few times, particularly with common routines from kernel32, advapi32, and user32. It's not worth taking the chance of a conflict with another package just to save a few keystrokes. The global loaders also don't allow setting use_errno=True or use_last_error=True, so the function pointers they create don't capture the C errno value for ctypes.get_errno() or Windows last error value for ctypes.get_last_error(). Calling kernel32.GetLastError() after the fact may not be reliable in a scripting environment even if it's called directly after the previous FFI call. _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/AHDEAUNZNUT6EWT7GTEGSKKFL3GABZ4W/ Code of Conduct: http://python.org/psf/codeofconduct/