alec

Abstraction Layer for Escape Codes
git clone git://git.dimitrijedobrota.com/alec.git
Log | Files | Refs | README | LICENSE |

alec.rules.hpp (5283B)


1 #ifndef ALEC_ALEC_H 2 #define ALEC_ALEC_H 3 4 #include <algorithm> 5 #include <array> 6 #include <assert.h> 7 #include <cstdint> 8 #include <string> 9 #include <type_traits> 10 11 12 namespace alec { 13 14 enum Ctrl { 15 BELL = 0x07, 16 BS = 0x08, 17 HT = 0x09, 18 LF = 0x0A, 19 VT = 0x0B, 20 FF = 0x0C, 21 CR = 0x0D, 22 ESC = 0x1B, 23 DEL = 0x7F, 24 }; 25 26 enum class Color { 27 BLACK = 0, 28 RED = 1, 29 GREEN = 2, 30 YELLOW = 3, 31 BLUE = 4, 32 MAGENTA = 5, 33 CYAN = 6, 34 WHITE = 7, 35 DEFAULT = 9, 36 }; 37 38 enum class Decor { 39 RESET = 0, 40 BOLD = 1, 41 DIM = 2, 42 ITALIC = 3, 43 UNDERLINE = 4, 44 BLINK = 5, 45 INVERSE = 7, 46 HIDE = 8, 47 STRIKE = 9, 48 }; 49 50 enum class Motion { 51 END = 0, 52 BEGIN = 1, 53 WHOLE = 2, 54 }; 55 56 namespace details { 57 58 template<std::size_t N> 59 struct string_literal 60 { 61 constexpr string_literal(const char (&str)[N]) : m_value(std::to_array(str)) {} 62 63 constexpr std::size_t size() const { return N; } 64 constexpr const char* data() const { return m_value.data(); } 65 66 std::array<char, N> m_value; 67 }; 68 69 namespace helper { 70 template <std::size_t N> static constexpr std::size_t size(string_literal<N> val) { return N; } 71 static constexpr std::size_t size(char val) { return 1; } 72 static constexpr std::size_t size(int val) { 73 std::size_t len = 1; 74 while (val /= 10) len++; 75 return len; 76 } 77 78 template <std::size_t N> static constexpr char *append(char *ptr, string_literal<N> val) { 79 std::copy_n(val.data(), N, ptr); 80 return ptr + N; 81 } 82 83 static constexpr char *append(char *ptr, char val) { 84 *ptr++ = val; 85 return ptr; 86 } 87 88 static constexpr char *append(char *ptr, int val) { 89 char *tmp = ptr += size(val); 90 do { 91 *--tmp = '0' + (val % 10); 92 } while (val /= 10); 93 return ptr; 94 } 95 96 static const std::string make(auto... args) { 97 std::string res((helper::size(args) + ... + 2), 0); 98 res[0] = Ctrl::ESC, res[1] = '['; 99 auto ptr = res.data() + 2; 100 ((ptr = helper::append(ptr, args)), ...); 101 return res; 102 } 103 104 105 template <auto... Args> struct escape_t { 106 static constexpr const auto value = []() { 107 std::array<char, (helper::size(Args) + ... + 3)> arr = {Ctrl::ESC, '[', 0}; 108 auto ptr = arr.data() + 2; 109 ((ptr = helper::append(ptr, Args)), ...); 110 return arr; 111 }(); 112 static constexpr auto data = value.data(); 113 }; 114 }; 115 116 template <auto... Args> static constexpr auto escape = helper::escape_t<Args...>().data; 117 template <details::string_literal... Strs> static constexpr auto escape_literal = escape<Strs...>; 118 119 } // namespace details 120 121 // Tamplate parameter constraints 122 123 template <int n> 124 concept limit_256_v = n >= 0 && n < 256; 125 126 template <int n> 127 concept limit_pos_v = n >= 0; 128 129 static inline bool limit_pos(int n) { return n >= 0; }; 130 static inline bool limit_256(int n) { return n >= 0 && n < 256; }; 131 132 %% 133 134 // Move cursor up/down/frwd/back 135 136 cursor_up 137 int n 138 limit_pos 139 n, 'A' 140 141 cursor_down 142 int n 143 limit_pos 144 n, 'B' 145 146 cursor_frwd 147 int n 148 limit_pos 149 n, 'C' 150 151 cursor_back 152 int n 153 limit_pos 154 n, 'D' 155 156 // Move cursor to the next/prev line 157 158 cursor_line_next 159 int n 160 limit_pos 161 n, 'E' 162 163 cursor_line_prev 164 int n 165 limit_pos 166 n, 'F' 167 168 // Set cursor to specific column 169 170 cursor_column 171 int n 172 limit_pos 173 n, 'G' 174 175 // Erase functions 176 177 erase_display 178 Motion m 179 | 180 (int)m, 'J' 181 182 erase_line 183 Motion m 184 | 185 (int)m, 'K' 186 187 // Scroll up/down 188 189 scroll_up 190 int n 191 limit_pos 192 n, 'S' 193 194 scroll_down 195 int n 196 limit_pos 197 n, 'T' 198 199 // Set cursor to a specific position 200 201 cursor_position 202 int n, int m 203 limit_pos 204 n, ';', m, 'H' 205 206 // color 207 208 // palet colors 209 210 foreground 211 Color color 212 | 213 (int)color + 30, 'm' 214 215 background 216 Color color 217 | 218 (int)color + 40, 'm' 219 220 // 256-color palette 221 222 foreground 223 int idx 224 limit_256 225 38, ';', 5, ';', idx, 'm' 226 227 background 228 int idx 229 limit_256 230 48, ';', 5, ';', idx, 'm' 231 232 // RGB colors 233 234 foreground 235 int R, int G, int B 236 limit_256 237 38, ';', 2, ';', R, ';', G, ';', B, 'm' 238 239 background 240 int R, int G, int B 241 limit_256 242 48, ';', 2, ';', R, ';', G, ';', B, 'm' 243 244 // Set/reset text decorators 245 246 decor_set 247 Decor decor 248 | 249 (int)decor, 'm' 250 251 decor_reset 252 Decor decor 253 | 254 (int)decor + 20, 'm' 255 256 // Save/restore cursor position; 257 258 cursor_save 259 | 260 | 261 's' 262 263 cursor_restore 264 | 265 | 266 'u' 267 268 // Set screen modes 269 270 screen_mode_set 271 int n 272 limit_pos 273 '=', n, 'h' 274 275 screen_mode_reset 276 int n 277 limit_pos 278 '=', n, 'l' 279 280 // Private screen modes supported by most terminals 281 282 // Save/restore screen 283 284 screen_save 285 | 286 | 287 "?47h" 288 289 screen_restore 290 | 291 | 292 "?47l" 293 294 // Show/hide cursor 295 296 cursor_show 297 | 298 | 299 "?25h" 300 301 cursor_hide 302 | 303 | 304 "?25l" 305 306 // Enable/disable alternate buffer 307 308 abuf_enable 309 | 310 | 311 "?1049h" 312 313 abuf_disable 314 | 315 | 316 "?1049l" 317 318 // Enable/disable bracketed paste mode 319 320 paste_enable 321 | 322 | 323 "?2004h" 324 325 paste_disable 326 | 327 | 328 "?2004l" 329 330 %% 331 332 // Keyboard string TODO 333 334 } // namespace ALEC 335 336 337 #endif