#include "utils.hpp" #include #include #include #include #include #include #include "iomanip.hpp" using namespace sc; term::term(int fd) { if (isatty(fd)) { 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 _ws.ws_row; } int term::cols() const { return _ws.ws_col; } void term::progress(int prefixlen, const std::string& prefix, double cur, double total) const { // 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 (cur > total) cur = total; int perclen = 5; int barwidth = cols() - perclen - prefixlen - 1; int maxsteps = barwidth * 8; int steps = round(cur * maxsteps / total); int perc = round(100 * cur / total); 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 << '%'; } // ------------------------------------------------------------------------ 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; }