diff --git a/src/iomanip.cpp b/src/iomanip.cpp index b29e367..40ef023 100644 --- a/src/iomanip.cpp +++ b/src/iomanip.cpp @@ -1,10 +1,14 @@ #include "iomanip.hpp" +#include + +using namespace sc::io; static std::ostream& gray(std::ostream& out, int val, int code) { if (val < 0 || val > 23) { throw std::invalid_argument("gray value out of range"); } - out << "\x1b[" << code << ";5;" << 232 + val << "m"; + if (isatty_ostream(out)) + out << "\x1b[" << code << ";5;" << 232 + val << "m"; return out; } @@ -12,152 +16,187 @@ static std::ostream& rgb(std::ostream& out, int r, int g, int b, int code) { if (r < 0 || r > 5 || g < 0 || g > 5 || b < 0 || b > 5) { throw std::invalid_argument("rgb color component out of range"); } - out << "\x1b[" << code << ";5;" << (16 + 36 * r + 6 * g + b) << "m"; + if (isatty_ostream(out)) + out << "\x1b[" << code << ";5;" << (16 + 36 * r + 6 * g + b) << "m"; return out; } +bool sc::io::isatty_ostream(const std::ostream& out) { + return (&out == &std::cout && isatty(STDOUT_FILENO)) || + (&out == &std::cerr && isatty(STDERR_FILENO)); +} + std::ostream& sc::io::hide_cursor(std::ostream& out) { - out << "\x1b[?25l"; + if (isatty_ostream(out)) + out << "\x1b[?25l"; return out; } std::ostream& sc::io::show_cursor(std::ostream& out) { - out << "\x1b[?25h"; + if (isatty_ostream(out)) + out << "\x1b[?25h"; return out; } std::ostream& sc::io::reset(std::ostream& out) { - out << "\x1b[m"; + if (isatty_ostream(out)) + out << "\x1b[m"; return out; } std::ostream& sc::io::bold(std::ostream& out) { - out << "\x1b[1m"; + if (isatty_ostream(out)) + out << "\x1b[1m"; return out; } std::ostream& sc::io::italic(std::ostream& out) { - out << "\x1b[3m"; + if (isatty_ostream(out)) + out << "\x1b[3m"; return out; } std::ostream& sc::io::underline(std::ostream& out) { - out << "\x1b[4m"; + if (isatty_ostream(out)) + out << "\x1b[4m"; return out; } std::ostream& sc::io::overline(std::ostream& out) { - out << "\x1b[53m"; + if (isatty_ostream(out)) + out << "\x1b[53m"; return out; } std::ostream& sc::io::strikethru(std::ostream& out) { - out << "\x1b[9m"; + if (isatty_ostream(out)) + out << "\x1b[9m"; return out; } std::ostream& sc::io::blinkslow(std::ostream& out) { - out << "\x1b[5m"; + if (isatty_ostream(out)) + out << "\x1b[5m"; return out; } std::ostream& sc::io::blinkfast(std::ostream& out) { - out << "\x1b[6m"; + if (isatty_ostream(out)) + out << "\x1b[6m"; return out; } std::ostream& sc::io::reverse(std::ostream& out) { - out << "\x1b[7m"; + if (isatty_ostream(out)) + out << "\x1b[7m"; return out; } std::ostream& sc::io::blackf(std::ostream& out) { - out << "\x1b[30m"; + if (isatty_ostream(out)) + out << "\x1b[30m"; return out; } std::ostream& sc::io::redf(std::ostream& out) { - out << "\x1b[31m"; + if (isatty_ostream(out)) + out << "\x1b[31m"; return out; } std::ostream& sc::io::greenf(std::ostream& out) { - out << "\x1b[32m"; + if (isatty_ostream(out)) + out << "\x1b[32m"; return out; } std::ostream& sc::io::yellowf(std::ostream& out) { - out << "\x1b[33m"; + if (isatty_ostream(out)) + out << "\x1b[33m"; return out; } std::ostream& sc::io::bluef(std::ostream& out) { - out << "\x1b[34m"; + if (isatty_ostream(out)) + out << "\x1b[34m"; return out; } std::ostream& sc::io::magentaf(std::ostream& out) { - out << "\x1b[35m"; + if (isatty_ostream(out)) + out << "\x1b[35m"; return out; } std::ostream& sc::io::cyanf(std::ostream& out) { - out << "\x1b[36m"; + if (isatty_ostream(out)) + out << "\x1b[36m"; return out; } std::ostream& sc::io::whitef(std::ostream& out) { - out << "\x1b[37m"; + if (isatty_ostream(out)) + out << "\x1b[37m"; return out; } std::ostream& sc::io::defaultf(std::ostream& out) { - out << "\x1b[39m"; + if (isatty_ostream(out)) + out << "\x1b[39m"; return out; } std::ostream& sc::io::blackb(std::ostream& out) { - out << "\x1b[40m"; + if (isatty_ostream(out)) + out << "\x1b[40m"; return out; } std::ostream& sc::io::redb(std::ostream& out) { - out << "\x1b[41m"; + if (isatty_ostream(out)) + out << "\x1b[41m"; return out; } std::ostream& sc::io::greenb(std::ostream& out) { - out << "\x1b[42m"; + if (isatty_ostream(out)) + out << "\x1b[42m"; return out; } std::ostream& sc::io::yellowb(std::ostream& out) { - out << "\x1b[43m"; + if (isatty_ostream(out)) + out << "\x1b[43m"; return out; } std::ostream& sc::io::blueb(std::ostream& out) { - out << "\x1b[44m"; + if (isatty_ostream(out)) + out << "\x1b[44m"; return out; } std::ostream& sc::io::magentab(std::ostream& out) { - out << "\x1b[45m"; + if (isatty_ostream(out)) + out << "\x1b[45m"; return out; } std::ostream& sc::io::cyanb(std::ostream& out) { - out << "\x1b[46m"; + if (isatty_ostream(out)) + out << "\x1b[46m"; return out; } std::ostream& sc::io::whiteb(std::ostream& out) { - out << "\x1b[47m"; + if (isatty_ostream(out)) + out << "\x1b[47m"; return out; } std::ostream& sc::io::defaultb(std::ostream& out) { - out << "\x1b[49m"; + if (isatty_ostream(out)) + out << "\x1b[49m"; return out; } diff --git a/src/iomanip.hpp b/src/iomanip.hpp index b161d68..5096c66 100644 --- a/src/iomanip.hpp +++ b/src/iomanip.hpp @@ -5,6 +5,8 @@ namespace sc { namespace io { + bool isatty_ostream(const std::ostream& out); + std::ostream& hide_cursor(std::ostream& out); std::ostream& show_cursor(std::ostream& out); diff --git a/src/utils.cpp b/src/utils.cpp index 014dcbb..9f98318 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -11,7 +11,8 @@ using namespace sc; term::term(int fd) { - if (isatty(fd)) { + _isatty = isatty(fd); + if (_isatty) { throw_if_min1(ioctl(fd, TIOCGWINSZ, &_ws)); } switch (fd) { @@ -22,11 +23,11 @@ term::term(int fd) { } int term::rows() const { - return _ws.ws_row; + return _isatty ? _ws.ws_row : 0; } int term::cols() const { - return _ws.ws_col; + return _isatty ? _ws.ws_col : 0; } void term::progress(int prefixlen, @@ -34,6 +35,8 @@ void term::progress(int prefixlen, double cur, double total) const { + if (!_isatty) return; + // use unicode to make nice bar const char* bar[8] = { u8"\u258F", u8"\u258E", u8"\u258D", u8"\u258C", diff --git a/src/utils.hpp b/src/utils.hpp index 9f84843..ee58410 100644 --- a/src/utils.hpp +++ b/src/utils.hpp @@ -12,6 +12,7 @@ namespace sc { class term { struct winsize _ws; std::ostream* _out {nullptr}; + bool _isatty {true}; public: term(int fd);