PRISMS-PF Manual
Loading...
Searching...
No Matches
terminal.h
Go to the documentation of this file.
1#pragma once
2
3#include <prismspf/config.h>
4
5#include <concepts>
6#include <cstdlib>
7#include <iostream>
8#include <ostream>
9#include <random>
10#include <span>
11#include <string>
12#include <string_view>
13
15
16template <typename T>
17concept StringLike = std::convertible_to<T, std::string_view>;
18
20{
21public:
22 TerminalColor() = delete;
23
24 // NOLINTBEGIN(readability-identifier-naming)
25
26 static constexpr std::string_view RESET = "\033[0m";
27
28 static constexpr std::string_view ERASE_SCREEN = "\033[2J";
29
30 static constexpr std::string_view BOLD = "\033[1m";
31 static constexpr std::string_view DIM = "\033[2m";
32 static constexpr std::string_view ITALIC = "\033[3m";
33 static constexpr std::string_view UNDERLINE = "\033[4m";
34 static constexpr std::string_view BLINK = "\033[5m";
35 static constexpr std::string_view STRIKE = "\033[9m";
36
37 static constexpr std::string_view BLACK = "\033[30m";
38 static constexpr std::string_view RED = "\033[31m";
39 static constexpr std::string_view GREEN = "\033[32m";
40 static constexpr std::string_view YELLOW = "\033[33m";
41 static constexpr std::string_view BLUE = "\033[34m";
42 static constexpr std::string_view MAGENTA = "\033[35m";
43 static constexpr std::string_view CYAN = "\033[36m";
44 static constexpr std::string_view WHITE = "\033[37m";
45 static constexpr std::string_view DEFAULT = "\033[39m";
46
47 static constexpr std::string_view BRIGHT_BLACK = "\033[90m";
48 static constexpr std::string_view BRIGHT_RED = "\033[91m";
49 static constexpr std::string_view BRIGHT_GREEN = "\033[92m";
50 static constexpr std::string_view BRIGHT_YELLOW = "\033[93m";
51 static constexpr std::string_view BRIGHT_BLUE = "\033[94m";
52 static constexpr std::string_view BRIGHT_MAGENTA = "\033[95m";
53 static constexpr std::string_view BRIGHT_CYAN = "\033[96m";
54 static constexpr std::string_view BRIGHT_WHITE = "\033[97m";
55
56 static constexpr std::string_view BG_BLACK = "\033[40m";
57 static constexpr std::string_view BG_RED = "\033[41m";
58 static constexpr std::string_view BG_GREEN = "\033[42m";
59 static constexpr std::string_view BG_YELLOW = "\033[43m";
60 static constexpr std::string_view BG_BLUE = "\033[44m";
61 static constexpr std::string_view BG_MAGENTA = "\033[45m";
62 static constexpr std::string_view BG_CYAN = "\033[46m";
63 static constexpr std::string_view BG_WHITE = "\033[47m";
64 static constexpr std::string_view BG_DEFAULT = "\033[49m";
65
66 static constexpr std::string_view BG_BRIGHT_BLACK = "\033[100m";
67 static constexpr std::string_view BG_BRIGHT_RED = "\033[101m";
68 static constexpr std::string_view BG_BRIGHT_GREEN = "\033[102m";
69 static constexpr std::string_view BG_BRIGHT_YELLOW = "\033[103m";
70 static constexpr std::string_view BG_BRIGHT_BLUE = "\033[104m";
71 static constexpr std::string_view BG_BRIGHT_MAGENTA = "\033[105m";
72 static constexpr std::string_view BG_BRIGHT_CYAN = "\033[106m";
73 static constexpr std::string_view BG_BRIGHT_WHITE = "\033[107m";
74
75 static constexpr std::string_view MY_ORANGE = "\033[38;5;166m";
76 static constexpr std::string_view MY_PURPLE = "\033[38;5;91m";
77 static constexpr std::string_view MY_BLUE = "\033[38;5;33m";
78 static constexpr std::string_view MY_GRAY = "\033[38;5;240m";
79
80 // NOLINTEND(readability-identifier-naming)
81
85 static std::string
86 colorize(const StringLike auto &text, std::string_view code)
87 {
88 return std::string(code) + std::string(text) + std::string(RESET);
89 }
90
94 static std::string
95 colorize(const StringLike auto &text, std::initializer_list<std::string_view> codes)
96 {
97 std::string prefix;
98 for (auto code : codes)
99 {
100 prefix += code;
101 }
102 return prefix + std::string(text) + std::string(RESET);
103 }
104
108 template <typename... Codes>
109 requires(std::convertible_to<Codes, std::string_view> && ...)
110 static std::string
111 colorize(const StringLike auto &text, [[maybe_unused]] Codes &&...codes)
112 {
113 std::string prefix;
114 ((prefix += std::string_view(codes)), ...);
115 return prefix + std::string(text) + std::string(RESET);
116 }
117
121 static std::string
122 tessellate(const StringLike auto &text,
123 std::initializer_list<std::string_view> codes,
124 std::size_t block_size = 1,
125 std::string_view modifier = "")
126 {
127 return tessellate_impl(std::string_view(text),
128 std::span(codes.begin(), codes.size()),
129 block_size,
130 modifier);
131 }
132
136 template <typename... Codes>
137 requires(std::convertible_to<Codes, std::string_view> && ...)
138 static std::string
139 tessellate(const StringLike auto &text,
140 std::size_t block_size,
141 std::string_view modifier,
142 [[maybe_unused]] Codes &&...codes)
143 {
144 auto code_arr = std::array {std::string_view(codes)...};
145 return tessellate_impl(std::string_view(text),
146 std::span(code_arr),
147 block_size,
148 modifier);
149 }
150
154 [[nodiscard]] static bool
155 is_supported() noexcept
156 {
157 return std::getenv("TERM") != nullptr || std::getenv("COLORTERM") != nullptr;
158 }
159
160private:
161 static std::string
162 tessellate_impl(std::string_view text,
163 std::span<const std::string_view> codes,
164 std::size_t block_size,
165 std::string_view modifier = "")
166 {
167 if (codes.empty() || text.empty())
168 {
169 return std::string(text);
170 }
171
172 static std::mt19937 rng {std::random_device {}()};
173 std::uniform_int_distribution<std::size_t> dist(0, codes.size() - 1);
174
175 std::string result;
176
177 std::size_t index = 0;
178 while (index < text.size())
179 {
180 result += modifier;
181 std::string_view code = codes[dist(rng)];
182 result += code;
183
184 // We deviate from the block size a little because we need to use the
185 // UTF-8 characters
186 std::size_t chars_written = 0;
187 std::size_t next_index = index;
188 while (next_index < text.size() && chars_written < block_size)
189 {
190 if (text[next_index] == '\n')
191 {
192 break;
193 }
194
195 constexpr uint8_t utf8_continuation_mask = 0xC0;
196 constexpr uint8_t utf8_continuation_pattern = 0x80;
197 next_index++;
198 while (next_index < text.size() &&
199 (static_cast<uint8_t>(text[next_index]) & utf8_continuation_mask) ==
200 utf8_continuation_pattern)
201 {
202 next_index++;
203 }
204 chars_written++;
205 }
206
207 result.append(text, index, next_index - index);
208 result += RESET;
209
210 if (next_index < text.size() && text[next_index] == '\n')
211 {
212 result += '\n';
213 next_index++;
214 }
215
216 index = next_index;
217 }
218
219 return result;
220 }
221};
222
223PRISMS_PF_END_NAMESPACE
static constexpr std::string_view MY_ORANGE
Definition terminal.h:75
static constexpr std::string_view BG_DEFAULT
Definition terminal.h:64
static constexpr std::string_view MY_PURPLE
Definition terminal.h:76
static constexpr std::string_view MY_GRAY
Definition terminal.h:78
static constexpr std::string_view BG_RED
Definition terminal.h:57
static constexpr std::string_view BG_BRIGHT_YELLOW
Definition terminal.h:69
static constexpr std::string_view BG_BRIGHT_BLUE
Definition terminal.h:70
static constexpr std::string_view BRIGHT_YELLOW
Definition terminal.h:50
static constexpr std::string_view BRIGHT_MAGENTA
Definition terminal.h:52
static constexpr std::string_view DEFAULT
Definition terminal.h:45
static constexpr std::string_view BRIGHT_RED
Definition terminal.h:48
static constexpr std::string_view MY_BLUE
Definition terminal.h:77
static constexpr std::string_view BRIGHT_BLACK
Definition terminal.h:47
static constexpr std::string_view BG_BRIGHT_BLACK
Definition terminal.h:66
static constexpr std::string_view RED
Definition terminal.h:38
static std::string tessellate(const StringLike auto &text, std::initializer_list< std::string_view > codes, std::size_t block_size=1, std::string_view modifier="")
Tessellate text with given styles.
Definition terminal.h:122
static constexpr std::string_view BG_MAGENTA
Definition terminal.h:61
static constexpr std::string_view BLACK
Definition terminal.h:37
static constexpr std::string_view BLUE
Definition terminal.h:41
TerminalColor()=delete
static constexpr std::string_view RESET
Definition terminal.h:26
static constexpr std::string_view ITALIC
Definition terminal.h:32
static constexpr std::string_view DIM
Definition terminal.h:31
static constexpr std::string_view BOLD
Definition terminal.h:30
static constexpr std::string_view BRIGHT_GREEN
Definition terminal.h:49
static std::string colorize(const StringLike auto &text, std::string_view code)
Wrap text in a single style.
Definition terminal.h:86
static constexpr std::string_view BRIGHT_WHITE
Definition terminal.h:54
static constexpr std::string_view ERASE_SCREEN
Definition terminal.h:28
static constexpr std::string_view WHITE
Definition terminal.h:44
static std::string tessellate_impl(std::string_view text, std::span< const std::string_view > codes, std::size_t block_size, std::string_view modifier="")
Definition terminal.h:162
static constexpr std::string_view BRIGHT_CYAN
Definition terminal.h:53
static constexpr std::string_view MAGENTA
Definition terminal.h:42
static constexpr std::string_view BG_BRIGHT_CYAN
Definition terminal.h:72
static constexpr std::string_view BG_CYAN
Definition terminal.h:62
static constexpr std::string_view BG_BLUE
Definition terminal.h:60
static constexpr std::string_view BG_BRIGHT_GREEN
Definition terminal.h:68
static constexpr std::string_view BG_WHITE
Definition terminal.h:63
static constexpr std::string_view BRIGHT_BLUE
Definition terminal.h:51
static constexpr std::string_view BG_BLACK
Definition terminal.h:56
static constexpr std::string_view UNDERLINE
Definition terminal.h:33
static constexpr std::string_view YELLOW
Definition terminal.h:40
static constexpr std::string_view BLINK
Definition terminal.h:34
static constexpr std::string_view BG_YELLOW
Definition terminal.h:59
static constexpr std::string_view BG_BRIGHT_RED
Definition terminal.h:67
static constexpr std::string_view GREEN
Definition terminal.h:39
static constexpr std::string_view BG_BRIGHT_MAGENTA
Definition terminal.h:71
static constexpr std::string_view BG_GREEN
Definition terminal.h:58
static bool is_supported() noexcept
Whether terminal supports ANSI codes.
Definition terminal.h:155
static constexpr std::string_view BG_BRIGHT_WHITE
Definition terminal.h:73
static constexpr std::string_view STRIKE
Definition terminal.h:35
static std::string colorize(const StringLike auto &text, std::initializer_list< std::string_view > codes)
Wrap text in multiple styles.
Definition terminal.h:95
static constexpr std::string_view CYAN
Definition terminal.h:43
Definition terminal.h:17
Definition conditional_ostreams.cc:20
Definition vectorized_operations.h:17