Allow using ANSI escape codes on windows when writing to the console

This commit is contained in:
Kovid Goyal 2019-12-04 17:59:40 +05:30
parent bd80269072
commit df70399661
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 35 additions and 17 deletions

View File

@ -36,6 +36,34 @@ log_error(const char *fmt, ...) {
va_end(ar);
fprintf(stderr, "\n");
}
static bool stdout_is_a_tty = false, stderr_is_a_tty = false;
DWORD console_old_mode = 0;
static bool console_mode_changed = false;
static void
detect_tty() {
stdout_is_a_tty = _isatty(_fileno(stdout));
stderr_is_a_tty = _isatty(_fileno(stderr));
}
static void
setup_vt_terminal_mode() {
if (stdout_is_a_tty || stderr_is_a_tty) {
HANDLE h = GetStdHandle(stdout_is_a_tty ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);
if (h != INVALID_HANDLE_VALUE) {
if (GetConsoleMode(h, &console_old_mode)) {
console_mode_changed = true;
SetConsoleMode(h, console_old_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
}
}
}
}
static void
restore_vt_terminal_mode() {
if (console_mode_changed) SetConsoleMode(GetStdHandle(stdout_is_a_tty ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE), console_old_mode);
}
#else
static void
log_error(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
@ -227,12 +255,14 @@ run_interpreter() {
#ifdef _WIN32
UINT code_page = GetConsoleOutputCP();
if (code_page != CP_UTF8) SetConsoleOutputCP(CP_UTF8);
setup_vt_terminal_mode();
#endif
int ret = Py_RunMain();
PyConfig_Clear(&config);
#ifdef _WIN32
if (code_page != CP_UTF8) SetConsoleOutputCP(CP_UTF8);
restore_vt_terminal_mode();
#endif
exit(ret);
#undef CHECK_STATUS

View File

@ -20,8 +20,6 @@
static int GUI_APP = 0;
static char python_dll[] = PYDLL;
void set_gui_app(int yes) { GUI_APP = yes; }
static int _show_error(const wchar_t *preamble, const wchar_t *msg, const int code) {
static wchar_t buf[4096];
static char utf8_buf[4096] = {0};
@ -105,20 +103,9 @@ load_python_dll() {
const static wchar_t out_of_memory[] = L"Out of memory";
UINT
setup_streams() {
UINT code_page = GetConsoleOutputCP();
SetConsoleOutputCP(CP_UTF8);
//printf("input cp: %d output cp: %d\r\n", GetConsoleCP(), GetConsoleOutputCP());
return code_page;
}
void
static void
redirect_out_stream(FILE *stream) {
if (_isatty(_fileno(stream))) return;
FILE *f = NULL;
errno_t err;
@ -151,13 +138,14 @@ execute_python_entrypoint(const wchar_t *basename, const wchar_t *module, const
int ret = 0;
// Prevent Windows' idiotic error dialog popups when various win32 api functions fail
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);
detect_tty();
if (is_gui_app) {
// Redirect stdout and stderr to NUL so that python does not fail writing to them
redirect_out_stream(stdout);
redirect_out_stream(stderr);
if (!stdout_is_a_tty) redirect_out_stream(stdout);
if (!stderr_is_a_tty) redirect_out_stream(stderr);
}
set_gui_app(is_gui_app);
GUI_APP = is_gui_app;
// Disable the invalid parameter handler
_set_invalid_parameter_handler(null_invalid_parameter_handler);
interpreter_data.argv = CommandLineToArgvW(GetCommandLineW(), &interpreter_data.argc);