ansi
parent
fcbc6b947d
commit
08e19c067e
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 3.20)
|
cmake_minimum_required(VERSION 3.20)
|
||||||
include(cmake/color.cmake)
|
include(cmake/color.cmake)
|
||||||
set(BLT_VERSION 5.1.10)
|
set(BLT_VERSION 5.1.11)
|
||||||
|
|
||||||
set(BLT_TARGET BLT)
|
set(BLT_TARGET BLT)
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,10 @@
|
||||||
#ifndef BLT_LOGGING_COLORS_H
|
#ifndef BLT_LOGGING_COLORS_H
|
||||||
#define BLT_LOGGING_COLORS_H
|
#define BLT_LOGGING_COLORS_H
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <variant>
|
||||||
#include <blt/std/types.h>
|
#include <blt/std/types.h>
|
||||||
|
|
||||||
#define BLT_ANSI_ESCAPE "\x1B"
|
#define BLT_ANSI_ESCAPE "\x1B"
|
||||||
|
@ -32,7 +35,9 @@ namespace blt::logging::ansi
|
||||||
{
|
{
|
||||||
namespace color
|
namespace color
|
||||||
{
|
{
|
||||||
enum class color_mode : i32
|
inline std::array<u8, 10> reset_sequences = {0, 22, 22, 23, 24, 25, 26, 27, 28, 29};
|
||||||
|
|
||||||
|
enum class color_mode : u8
|
||||||
{
|
{
|
||||||
RESET_ALL = 0,
|
RESET_ALL = 0,
|
||||||
BOLD = 1,
|
BOLD = 1,
|
||||||
|
@ -42,10 +47,9 @@ namespace blt::logging::ansi
|
||||||
BLINK = 5,
|
BLINK = 5,
|
||||||
REVERSE = 7,
|
REVERSE = 7,
|
||||||
HIDDEN = 8,
|
HIDDEN = 8,
|
||||||
STRIKE_THROUGH = 9,
|
STRIKE_THROUGH = 9, };
|
||||||
};
|
|
||||||
|
|
||||||
enum class color8 : i32
|
enum class color8 : u8
|
||||||
{
|
{
|
||||||
BLACK = 0,
|
BLACK = 0,
|
||||||
RED = 1,
|
RED = 1,
|
||||||
|
@ -58,7 +62,7 @@ namespace blt::logging::ansi
|
||||||
DEFAULT = 9
|
DEFAULT = 9
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class color8_bright : i32
|
enum class color8_bright : u8
|
||||||
{
|
{
|
||||||
BLACK = 0,
|
BLACK = 0,
|
||||||
RED = 1,
|
RED = 1,
|
||||||
|
@ -67,33 +71,161 @@ namespace blt::logging::ansi
|
||||||
BLUE = 4,
|
BLUE = 4,
|
||||||
MAGENTA = 5,
|
MAGENTA = 5,
|
||||||
CYAN = 6,
|
CYAN = 6,
|
||||||
WHITE = 7,
|
WHITE = 7, };
|
||||||
|
|
||||||
|
struct rgb_t
|
||||||
|
{
|
||||||
|
u8 r, g, b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct color256
|
||||||
|
{
|
||||||
|
explicit color256(u8 index) : color(index)
|
||||||
|
{}
|
||||||
|
|
||||||
|
color256(const u8 r, const u8 g, const u8 b) : color(rgb_t{r, g, b})
|
||||||
|
{
|
||||||
|
if (r > 5)
|
||||||
|
throw std::invalid_argument("r must be between 0 and 5");
|
||||||
|
if (g > 5)
|
||||||
|
throw std::invalid_argument("g must be between 0 and 5");
|
||||||
|
if (b > 5)
|
||||||
|
throw std::invalid_argument("b must be between 0 and 5");
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] u8 index() const
|
||||||
|
{
|
||||||
|
if (std::holds_alternative<u8>(color))
|
||||||
|
return std::get<u8>(color);
|
||||||
|
const auto [r, g, b] = std::get<rgb_t>(color);
|
||||||
|
return (r * 36) + (g * 6) + b + 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::variant<u8, rgb_t> color;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct color_rgb
|
||||||
|
{
|
||||||
|
color_rgb(const u8 r, const u8 g, const u8 b) : color(rgb_t{r, g, b})
|
||||||
|
{}
|
||||||
|
|
||||||
|
rgb_t color;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct color_converter
|
struct color_holder
|
||||||
{
|
{
|
||||||
|
using value_type = T;
|
||||||
|
|
||||||
|
T color;
|
||||||
|
bool alt = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct color_converter
|
||||||
|
{};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct color_converter<color8>
|
struct color_converter<color8>
|
||||||
{
|
{
|
||||||
static std::string to_string(color8 color, const bool background)
|
static std::string to_string(const color_holder<color8> color)
|
||||||
{
|
{
|
||||||
return (background ? "4" : "3") + std::to_string(static_cast<i32>(color));
|
return (color.alt ? "4" : "3") + std::to_string(static_cast<u8>(color.color));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct color_converter<color8_bright>
|
struct color_converter<color8_bright>
|
||||||
{
|
{
|
||||||
static std::string to_string(color8_bright color, const bool background)
|
static std::string to_string(const color_holder<color8_bright> color)
|
||||||
{
|
{
|
||||||
return (background ? "10" : "9") + std::to_string(static_cast<i32>(color));
|
return (color.alt ? "10" : "9") + std::to_string(static_cast<u8>(color.color));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct color_converter<color_mode>
|
||||||
|
{
|
||||||
|
static std::string to_string(const color_holder<color_mode> color)
|
||||||
|
{
|
||||||
|
return color.alt ? std::to_string(reset_sequences[static_cast<u8>(color.color)]) : std::to_string(static_cast<u8>(color.color));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct color_converter<color256>
|
||||||
|
{
|
||||||
|
static std::string to_string(const color_holder<color256> color)
|
||||||
|
{
|
||||||
|
return (color.alt ? "48;5;" : "38;5;") + std::to_string(color.color.index());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct color_converter<color_rgb>
|
||||||
|
{
|
||||||
|
static std::string to_string(const color_holder<color_rgb> color)
|
||||||
|
{
|
||||||
|
return (color.alt ? "48;2;" : "38;2;") + std::to_string(color.color.color.r) + ";" + std::to_string(color.color.color.g) + ";" +
|
||||||
|
std::to_string(color.color.color.b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct ensure_holder
|
||||||
|
{
|
||||||
|
static color_holder<T> make(const T& color)
|
||||||
|
{
|
||||||
|
return color_holder<T>{color, false};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct ensure_holder<color_holder<T>>
|
||||||
|
{
|
||||||
|
static color_holder<T> make(const color_holder<T>& color)
|
||||||
|
{
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct decay
|
||||||
|
{
|
||||||
|
using type = std::decay_t<T>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct decay<color_holder<T>>
|
||||||
|
{
|
||||||
|
using type = std::decay_t<T>;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using decay_t = typename decay<T>::type;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
auto fg(const T& color)
|
||||||
|
{
|
||||||
|
return detail::color_holder<T>{color, false};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
auto bg(const T& color)
|
||||||
|
{
|
||||||
|
return detail::color_holder<T>{color, true};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
std::string build(const Args&... args)
|
||||||
|
{
|
||||||
|
std::string result = BLT_ANSI_CSI;
|
||||||
|
((result += detail::color_converter<detail::decay_t<Args>>::to_string(detail::ensure_holder<Args>::make(args)), result += ';'), ...);
|
||||||
|
return result.substr(0, result.size() - 1) + "m";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +239,7 @@ namespace blt::logging::ansi
|
||||||
inline const std::string form_feed = "\x0C";
|
inline const std::string form_feed = "\x0C";
|
||||||
inline const std::string carriage_return = "\x0D";
|
inline const std::string carriage_return = "\x0D";
|
||||||
inline const std::string escape = BLT_ANSI_ESCAPE;
|
inline const std::string escape = BLT_ANSI_ESCAPE;
|
||||||
inline const std::string del = "\0x7F";
|
inline const std::string del = "\x7F";
|
||||||
inline const std::string csi = BLT_ANSI_CSI;
|
inline const std::string csi = BLT_ANSI_CSI;
|
||||||
inline const std::string dsc = BLT_ANSI_DSC;
|
inline const std::string dsc = BLT_ANSI_DSC;
|
||||||
inline const std::string osc = BLT_ANSI_OSC;
|
inline const std::string osc = BLT_ANSI_OSC;
|
||||||
|
@ -118,7 +250,7 @@ namespace blt::logging::ansi
|
||||||
inline const std::string home = BLT_ANSI_CSI "H";
|
inline const std::string home = BLT_ANSI_CSI "H";
|
||||||
|
|
||||||
template <bool UseH>
|
template <bool UseH>
|
||||||
inline std::string move_to(i64 line, i64 column)
|
std::string move_to(const i64 line, const i64 column)
|
||||||
{
|
{
|
||||||
if constexpr (UseH)
|
if constexpr (UseH)
|
||||||
return std::string(BLT_ANSI_CSI) + std::to_string(line) + ";" + std::to_string(column) + "H";
|
return std::string(BLT_ANSI_CSI) + std::to_string(line) + ";" + std::to_string(column) + "H";
|
||||||
|
@ -126,37 +258,37 @@ namespace blt::logging::ansi
|
||||||
return std::string(BLT_ANSI_CSI) + std::to_string(line) + ";" + std::to_string(column) + "f";
|
return std::string(BLT_ANSI_CSI) + std::to_string(line) + ";" + std::to_string(column) + "f";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string move_up(i64 lines)
|
inline std::string move_up(const i64 lines)
|
||||||
{
|
{
|
||||||
return std::string(BLT_ANSI_CSI) + std::to_string(lines) + "A";
|
return std::string(BLT_ANSI_CSI) + std::to_string(lines) + "A";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string move_down(i64 lines)
|
inline std::string move_down(const i64 lines)
|
||||||
{
|
{
|
||||||
return std::string(BLT_ANSI_CSI) + std::to_string(lines) + "B";
|
return std::string(BLT_ANSI_CSI) + std::to_string(lines) + "B";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string move_right(i64 columns)
|
inline std::string move_right(const i64 columns)
|
||||||
{
|
{
|
||||||
return std::string(BLT_ANSI_CSI) + std::to_string(columns) + "C";
|
return std::string(BLT_ANSI_CSI) + std::to_string(columns) + "C";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string move_left(i64 columns)
|
inline std::string move_left(const i64 columns)
|
||||||
{
|
{
|
||||||
return std::string(BLT_ANSI_CSI) + std::to_string(columns) + "D";
|
return std::string(BLT_ANSI_CSI) + std::to_string(columns) + "D";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string move_begin_down(i64 lines)
|
inline std::string move_begin_down(const i64 lines)
|
||||||
{
|
{
|
||||||
return std::string(BLT_ANSI_CSI) + std::to_string(lines) + "E";
|
return std::string(BLT_ANSI_CSI) + std::to_string(lines) + "E";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string move_begin_up(i64 lines)
|
inline std::string move_begin_up(const i64 lines)
|
||||||
{
|
{
|
||||||
return std::string(BLT_ANSI_CSI) + std::to_string(lines) + "F";
|
return std::string(BLT_ANSI_CSI) + std::to_string(lines) + "F";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string move_to(i64 column)
|
inline std::string move_to(const i64 column)
|
||||||
{
|
{
|
||||||
return std::string(BLT_ANSI_CSI) + std::to_string(column) + "G";
|
return std::string(BLT_ANSI_CSI) + std::to_string(column) + "G";
|
||||||
}
|
}
|
||||||
|
@ -164,9 +296,9 @@ namespace blt::logging::ansi
|
||||||
inline const std::string request_cursor_position = BLT_ANSI_CSI "6n";
|
inline const std::string request_cursor_position = BLT_ANSI_CSI "6n";
|
||||||
inline const std::string move_up_one_line = BLT_ANSI_ESCAPE " M";
|
inline const std::string move_up_one_line = BLT_ANSI_ESCAPE " M";
|
||||||
inline const std::string save_cursor_position_dec = BLT_ANSI_ESCAPE " 7";
|
inline const std::string save_cursor_position_dec = BLT_ANSI_ESCAPE " 7";
|
||||||
inline const std::string resotre_cursor_position_dec = BLT_ANSI_ESCAPE " 8";
|
inline const std::string restore_cursor_position_dec = BLT_ANSI_ESCAPE " 8";
|
||||||
inline const std::string save_cursor_position_sco = BLT_ANSI_CSI "s";
|
inline const std::string save_cursor_position_sco = BLT_ANSI_CSI "s";
|
||||||
inline const std::string resotre_cursor_position_sco = BLT_ANSI_CSI "u";
|
inline const std::string restore_cursor_position_sco = BLT_ANSI_CSI "u";
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace erase
|
namespace erase
|
||||||
|
@ -179,6 +311,30 @@ namespace blt::logging::ansi
|
||||||
inline const std::string from_begin_of_line = BLT_ANSI_CSI "1K";
|
inline const std::string from_begin_of_line = BLT_ANSI_CSI "1K";
|
||||||
inline const std::string entire_line = BLT_ANSI_CSI "2K";
|
inline const std::string entire_line = BLT_ANSI_CSI "2K";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum class mode : u8
|
||||||
|
{
|
||||||
|
mono40x25_text = 0,
|
||||||
|
color40x25_text = 1,
|
||||||
|
mono80x25_text = 2,
|
||||||
|
color80x25_text = 3,
|
||||||
|
color320x200_4color_graphics = 4,
|
||||||
|
mono320x200_graphics = 5,
|
||||||
|
mono640x200_graphics = 6,
|
||||||
|
line_wrapping = 7,
|
||||||
|
color320x200_graphics = 13,
|
||||||
|
color640x200_16color_graphics = 14,
|
||||||
|
mono640x350_2color_graphics = 15,
|
||||||
|
color640x350_16color_graphics = 16,
|
||||||
|
mono640x480_2color_graphics = 17,
|
||||||
|
color640x480_16color_graphics = 18,
|
||||||
|
color320_200_256color_graphics = 19
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::string use_mode(const mode mode)
|
||||||
|
{
|
||||||
|
return std::string(BLT_ANSI_CSI) + "=" + std::to_string(static_cast<u8>(mode)) + "h";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //BLT_LOGGING_COLORS_H
|
#endif //BLT_LOGGING_COLORS_H
|
||||||
|
|
|
@ -130,8 +130,14 @@ namespace blt::logging
|
||||||
default:
|
default:
|
||||||
handle_type(stream, type);
|
handle_type(stream, type);
|
||||||
if constexpr (blt::meta::is_streamable_v<T>)
|
if constexpr (blt::meta::is_streamable_v<T>)
|
||||||
stream << t;
|
{
|
||||||
|
if constexpr (std::is_same_v<T, char> || std::is_same_v<T, signed char>)
|
||||||
|
stream << static_cast<int>(t);
|
||||||
|
else if constexpr (std::is_same_v<T, unsigned char>)
|
||||||
|
stream << static_cast<unsigned int>(t);
|
||||||
else
|
else
|
||||||
|
stream << t;
|
||||||
|
}else
|
||||||
stream << "{INVALID TYPE}";
|
stream << "{INVALID TYPE}";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 7ef2e733416953b222851f9a360d7fc72d068ee5
|
Subproject commit 93201da2ba5a6aba0a6e57ada64973555629b3e3
|
|
@ -17,13 +17,13 @@
|
||||||
*/
|
*/
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <blt/logging/ansi.h>
|
||||||
#include <blt/logging/logging.h>
|
#include <blt/logging/logging.h>
|
||||||
#include <blt/std/assert.h>
|
#include <blt/std/assert.h>
|
||||||
#include <blt/std/utility.h>
|
#include <blt/std/utility.h>
|
||||||
|
|
||||||
struct some_silly_type_t
|
struct some_silly_type_t
|
||||||
{
|
{};
|
||||||
};
|
|
||||||
|
|
||||||
auto expected_str = std::string(R"(This is a println!
|
auto expected_str = std::string(R"(This is a println!
|
||||||
This is a println with args '42'
|
This is a println with args '42'
|
||||||
|
@ -131,5 +131,27 @@ int main()
|
||||||
auto [passed, error_msg] = compare_strings(expected_str, ss.str());
|
auto [passed, error_msg] = compare_strings(expected_str, ss.str());
|
||||||
BLT_ASSERT_MSG(passed && "Logger logged string doesn't match precomputed expected string!", error_msg.c_str());
|
BLT_ASSERT_MSG(passed && "Logger logged string doesn't match precomputed expected string!", error_msg.c_str());
|
||||||
|
|
||||||
|
namespace ansi = blt::logging::ansi;
|
||||||
|
namespace color = ansi::color;
|
||||||
|
|
||||||
|
for (blt::u8 r = 0; r < 6; r++)
|
||||||
|
{
|
||||||
|
for (blt::u8 g = 0; g < 6; g++)
|
||||||
|
{
|
||||||
|
for (blt::u8 b = 0; b < 6; b++)
|
||||||
|
{
|
||||||
|
blt::logging::println("{}This is a println with a color {:#3x} {:#3x} {:#3x}{}",
|
||||||
|
build(fg(color::color256{r, g, b}), bg(color::color256{
|
||||||
|
static_cast<unsigned char>(5 - r),
|
||||||
|
static_cast<unsigned char>(5 - g),
|
||||||
|
static_cast<unsigned char>(5 - b)
|
||||||
|
})), r, g, b, build(color::color_mode::RESET_ALL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
blt::logging::println("{}This is a color now with background{}",
|
||||||
|
build(color::color_mode::BOLD, fg(color::color8::CYAN), color::color_mode::DIM, bg(color::color8::YELLOW)),
|
||||||
|
build(color::color_mode::RESET_ALL));
|
||||||
|
|
||||||
// blt::logging::println("This is println {}\twith a std::endl in the middle of it");
|
// blt::logging::println("This is println {}\twith a std::endl in the middle of it");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue