Pārlūkot izejas kodu

LogStream: Add a simple-ish mechanism for colorizing and styling output.

Meet TStyle. It allows you to write things like this:

    dbg() << TStyle(TStyle::Red, TStyle::Bold) << "Hello, friends!";

Any style used will be reset along with the newline emitted when the dbg()
temporary goes out of scope. :^)

This can definitely be improved, but I think it's a decent place to start.
Andreas Kling 6 gadi atpakaļ
vecāks
revīzija
8075ba5064
2 mainītis faili ar 74 papildinājumiem un 1 dzēšanām
  1. 18 0
      AK/LogStream.cpp
  2. 56 1
      AK/LogStream.h

+ 18 - 0
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;
+}
+
 }

+ 56 - 1
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;