mirror of
https://github.com/mhx/dwarfs.git
synced 2025-09-07 19:41:54 -04:00
Fancy console output for Windows
This commit is contained in:
parent
3364972027
commit
6770c13c08
@ -43,6 +43,8 @@ class console_writer : public logger {
|
||||
level_type threshold, display_mode mode = NORMAL,
|
||||
bool verbose = false);
|
||||
|
||||
~console_writer();
|
||||
|
||||
void write(level_type level, const std::string& output, char const* file,
|
||||
int line) override;
|
||||
|
||||
|
@ -48,6 +48,8 @@ enum class termcolor {
|
||||
|
||||
bool stream_is_fancy_terminal(std::ostream& os);
|
||||
|
||||
bool set_cursor_state(bool enabled);
|
||||
|
||||
char const* terminal_color(termcolor color);
|
||||
|
||||
std::string
|
||||
|
@ -75,18 +75,29 @@ console_writer::console_writer(std::ostream& os, progress_mode pg_mode,
|
||||
} else {
|
||||
set_policy<prod_logger_policy>();
|
||||
}
|
||||
set_cursor_state(false);
|
||||
}
|
||||
|
||||
console_writer::~console_writer() { set_cursor_state(true); }
|
||||
|
||||
void console_writer::rewind() {
|
||||
if (!statebuf_.empty()) {
|
||||
int lines = 0;
|
||||
|
||||
switch (mode_) {
|
||||
case NORMAL:
|
||||
os_ << "\x1b[A\r\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A\x1b[A";
|
||||
lines = 8;
|
||||
break;
|
||||
case REWRITE:
|
||||
os_ << "\x1b[A\r\x1b[A\x1b[A\x1b[A";
|
||||
lines = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
os_ << '\r';
|
||||
|
||||
for (int i = 0; i < lines; ++i) {
|
||||
os_ << "\x1b[A";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,17 +26,68 @@
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <folly/portability/Unistd.h>
|
||||
#include <folly/portability/Windows.h>
|
||||
|
||||
#include "dwarfs/terminal.h"
|
||||
|
||||
namespace dwarfs {
|
||||
|
||||
#if defined(_WIN32)
|
||||
void WindowsEmulateVT100Terminal(DWORD std_handle) {
|
||||
static bool done = false;
|
||||
|
||||
if (done) {
|
||||
return;
|
||||
}
|
||||
|
||||
done = true;
|
||||
|
||||
// TODO?
|
||||
// ::SetConsoleOutputCP(CP_UTF8);
|
||||
// ::SetConsoleCP(CP_UTF8);
|
||||
|
||||
// Enable VT processing on stdout and stdin
|
||||
auto hdl = ::GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
DWORD out_mode = 0;
|
||||
::GetConsoleMode(hdl, &out_mode);
|
||||
|
||||
// https://docs.microsoft.com/en-us/windows/console/setconsolemode
|
||||
static constexpr DWORD enable_virtual_terminal_processing = 0x0004;
|
||||
static constexpr DWORD disable_newline_auto_return = 0x0008;
|
||||
out_mode |= enable_virtual_terminal_processing;
|
||||
out_mode |= disable_newline_auto_return;
|
||||
|
||||
::SetConsoleMode(hdl, out_mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool set_cursor_state(bool enabled [[maybe_unused]]) {
|
||||
bool was_enabled = true;
|
||||
#ifdef _WIN32
|
||||
auto hdl = ::GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
::CONSOLE_CURSOR_INFO cursorInfo;
|
||||
|
||||
::GetConsoleCursorInfo(hdl, &cursorInfo);
|
||||
was_enabled = cursorInfo.bVisible;
|
||||
cursorInfo.bVisible = enabled;
|
||||
::SetConsoleCursorInfo(hdl, &cursorInfo);
|
||||
#endif
|
||||
return was_enabled;
|
||||
}
|
||||
|
||||
bool stream_is_fancy_terminal(std::ostream& os [[maybe_unused]]) {
|
||||
#ifdef _WIN32
|
||||
// TODO
|
||||
if (&os == &std::cout) {
|
||||
WindowsEmulateVT100Terminal(STD_OUTPUT_HANDLE);
|
||||
return true;
|
||||
}
|
||||
if (&os == &std::cerr) {
|
||||
WindowsEmulateVT100Terminal(STD_ERROR_HANDLE);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
#else
|
||||
if (&os == &std::cout && !::isatty(::fileno(stdout))) {
|
||||
|
@ -114,9 +114,19 @@ const std::map<std::string, console_writer::progress_mode> progress_modes{
|
||||
{"none", console_writer::NONE},
|
||||
{"simple", console_writer::SIMPLE},
|
||||
{"ascii", console_writer::ASCII},
|
||||
#ifndef _WIN32
|
||||
{"unicode", console_writer::UNICODE},
|
||||
#endif
|
||||
};
|
||||
|
||||
const std::string default_progress_mode =
|
||||
#ifdef _WIN32
|
||||
"ascii"
|
||||
#else
|
||||
"unicode"
|
||||
#endif
|
||||
;
|
||||
|
||||
const std::map<std::string, debug_filter_mode> debug_filter_modes{
|
||||
{"included", debug_filter_mode::INCLUDED},
|
||||
{"included-files", debug_filter_mode::INCLUDED_FILES},
|
||||
@ -539,7 +549,7 @@ int mkdwarfs_main(int argc, sys_char** argv) {
|
||||
po::value<std::string>(&log_level_str)->default_value("info"),
|
||||
"log level (error, warn, info, debug, trace)")
|
||||
("progress",
|
||||
po::value<std::string>(&progress_mode)->default_value("unicode"),
|
||||
po::value<std::string>(&progress_mode)->default_value(default_progress_mode),
|
||||
progress_desc.c_str())
|
||||
("no-progress",
|
||||
po::value<bool>(&no_progress)->zero_tokens(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user