#include #include #include #include #include #include #include "utils.hpp" #include "iomanip.hpp" using namespace sc; term::term(int fd) { _isatty = isatty(fd); if (_isatty) { throw_if_min1(ioctl(fd, TIOCGWINSZ, &_ws)); } switch (fd) { case STDOUT_FILENO: _out = &std::cout; break; case STDERR_FILENO: _out = &std::cerr; break; default: break; } } int term::rows() const { return _isatty ? _ws.ws_row : 0; } int term::cols() const { return _isatty ? _ws.ws_col : 0; } void term::progress(int prefixlen, const std::string& prefix, double cur, double total) const { progress(prefixlen, prefix, cur / total); } void term::progress(int prefixlen, const std::string& prefix, double fraction) const { if (!_isatty) return; // use unicode to make nice bar const char* bar[8] = { u8"\u258F", u8"\u258E", u8"\u258D", u8"\u258C", u8"\u258B", u8"\u258A", u8"\u2589", u8"\u2588" }; if (fraction > 1) fraction = 1.0; int perclen = 5; int barwidth = cols() - perclen - prefixlen - 1; int maxsteps = barwidth * 8; int steps = round(fraction * maxsteps); int perc = round(100 * fraction); int fill_len = barwidth - steps / 8; *_out << '\r' << std::setw(prefixlen) << prefix.substr(0, prefixlen) << ' ' << io::grayf(8); for (int i = 0; i < steps / 8; ++i) { *_out << bar[7]; } if (steps % 8) { *_out << bar[steps % 8 - 1]; fill_len--; } *_out << io::reset << std::string(fill_len, ' '); *_out << ' ' << std::setw(3) << perc << '%'; } bool term::has_truecolor() { char* tc = getenv("COLORTERM"); std::string colorterm {tc ? tc : ""}; return colorterm.size() > 0 && (colorterm == "truecolor" || colorterm == "24bit"); } // ------------------------------------------------------------------------ cursor_hider::cursor_hider(std::ostream* out) : _out {out} { *_out << io::hide_cursor; } cursor_hider::~cursor_hider() { *_out << io::show_cursor; } // ------------------------------------------------------------------------ sc::io::clear_line::clear_line(const term& t) : _term {t} {} std::ostream& sc::io::operator<<(std::ostream& out, const sc::io::clear_line& obj) { out << '\r' << std::string(obj._term.cols(), ' ') << '\r'; return out; }