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