diff --git a/AK/LogStream.cpp b/AK/LogStream.cpp index ab0caeb57c..4d64179843 100644 --- a/AK/LogStream.cpp +++ b/AK/LogStream.cpp @@ -31,4 +31,22 @@ const LogStream& operator<<(const LogStream& stream, const void* value) return stream << String::format("%p", value); } +const LogStream& operator<<(const LogStream& stream, const TStyle& style) +{ + stream << "\033["; + + if (style.color() != TStyle::Color::NoColor) + stream << ((int)style.color() + 30) << (style.attributes() ? ";" : ""); + else + stream << '0'; + + if (style.attributes() & TStyle::Attribute::Bold) + stream << '1'; + + stream << 'm'; + + stream.m_needs_style_reset = true; + return stream; +} + } diff --git a/AK/LogStream.h b/AK/LogStream.h index 44ee51df09..e5906a776f 100644 --- a/AK/LogStream.h +++ b/AK/LogStream.h @@ -7,12 +7,63 @@ namespace AK { class String; class StringView; +class TStyle { +public: + enum NoneTag { DummyValue }; + static NoneTag None; + + enum Color { + Black = 0, + Red, + Green, + Brown, + Blue, + Magenta, + Cyan, + LightGray, + DarkGray, + BrightRed, + BrightGreen, + Yellow, + BrightBlue, + BrightMagenta, + BrightCyan, + White, + NoColor = 255, + }; + enum Attribute { + NoAttribute = 0, + Bold = 1, + }; + + TStyle() {} + TStyle(NoneTag) {} + TStyle(Color color, unsigned attributes = NoAttribute) + : m_color(color) + , m_attributes(attributes) + { + } + + ~TStyle() {} + + Color color() const { return m_color; } + unsigned attributes() const { return m_attributes; } + +private: + Color m_color { NoColor }; + unsigned m_attributes { NoAttribute }; +}; + class LogStream { public: LogStream() {} virtual ~LogStream() {} virtual void write(const char*, int) const = 0; + +protected: + friend const LogStream& operator<<(const LogStream&, const TStyle&); + mutable bool m_needs_style_reset { false }; }; class DebugLogStream final : public LogStream { @@ -20,6 +71,8 @@ public: DebugLogStream() {} virtual ~DebugLogStream() override { + if (m_needs_style_reset) + write("\033[0m", 4); char newline = '\n'; write(&newline, 1); } @@ -51,6 +104,7 @@ const LogStream& operator<<(const LogStream&, const StringView&); const LogStream& operator<<(const LogStream&, int); const LogStream& operator<<(const LogStream&, unsigned); const LogStream& operator<<(const LogStream&, const void*); +const LogStream& operator<<(const LogStream& stream, const TStyle&); inline const LogStream& operator<<(const LogStream& stream, char value) { @@ -65,5 +119,6 @@ inline const LogStream& operator<<(const LogStream& stream, bool value) } -using AK::LogStream; using AK::dbg; +using AK::LogStream; +using AK::TStyle;