alec.rules.hpp (5487B)
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> struct string_literal { 59 consteval string_literal(const char (&str)[N]) { std::copy_n(str, N, value); } 60 consteval std::size_t size() const { return N; } 61 62 char value[N]; 63 }; 64 65 struct helper { 66 template <typename T> static consteval std::size_t size(T val); 67 template <typename T> static constexpr char *append(char *ptr, T val); 68 69 template <std::size_t N> static constexpr std::size_t size(string_literal<N> val) { return val.size(); } 70 static constexpr std::size_t size(char val) { return 1; } 71 static constexpr std::size_t size(int val) { 72 std::size_t len = 1; 73 while (val /= 10) 74 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.value, 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::size_t len = (helper::size(args) + ... + 2); 98 std::string res(len, 'a'); 99 res[0] = Ctrl::ESC, res[1] = '['; 100 auto map = [ptr = res.data() + 2](auto const &s) mutable { ptr = helper::append(ptr, s); }; 101 (map(args), ...); 102 res[len] = 0; 103 return res; 104 } 105 }; 106 107 template <auto... Args> struct escape_t { 108 static constexpr const auto value = []() { 109 constexpr std::size_t len = (helper::size(Args) + ... + 2); 110 std::array<char, len + 1> arr{Ctrl::ESC, '[', 0}; 111 auto map = [ptr = arr.data() + 2](auto const &s) mutable { ptr = helper::append(ptr, s); }; 112 (map(Args), ...); 113 arr[len] = 0; 114 return arr; 115 }(); 116 }; 117 118 template <auto... Strs> static constexpr auto escape = escape_t<Strs...>::value.data(); 119 template <details::string_literal... Strs> static constexpr auto escape_literal = escape<Strs...>; 120 121 } // namespace details 122 123 // Tamplate parameter constraints 124 125 template <int n> 126 concept limit_256_v = n >= 0 && n < 256; 127 128 template <int n> 129 concept limit_pos_v = n >= 0; 130 131 static inline bool limit_pos(int n) { return n >= 0; }; 132 static inline bool limit_256(int n) { return n >= 0 && n < 256; }; 133 134 %% 135 136 // Move cursor up/down/frwd/back 137 138 cursor_up 139 int n 140 limit_pos 141 n, 'A' 142 143 cursor_down 144 int n 145 limit_pos 146 n, 'B' 147 148 cursor_frwd 149 int n 150 limit_pos 151 n, 'C' 152 153 cursor_back 154 int n 155 limit_pos 156 n, 'D' 157 158 // Move cursor to the next/prev line 159 160 cursor_line_next 161 int n 162 limit_pos 163 n, 'E' 164 165 cursor_line_prev 166 int n 167 limit_pos 168 n, 'F' 169 170 // Set cursor to specific column 171 172 cursor_column 173 int n 174 limit_pos 175 n, 'G' 176 177 // Erase functions 178 179 erase_display 180 Motion m 181 | 182 (int)m, 'J' 183 184 erase_line 185 Motion m 186 | 187 (int)m, 'K' 188 189 // Scroll up/down 190 191 scroll_up 192 int n 193 limit_pos 194 n, 'S' 195 196 scroll_down 197 int n 198 limit_pos 199 n, 'T' 200 201 // Set cursor to a specific position 202 203 cursor_position 204 int n, int m 205 limit_pos 206 n, ';', m, 'H' 207 208 // color 209 210 // palet colors 211 212 foreground 213 Color color 214 | 215 (int)color + 30, 'm' 216 217 background 218 Color color 219 | 220 (int)color + 40, 'm' 221 222 // 256-color palette 223 224 foreground 225 int idx 226 limit_256 227 38, ';', 5, ';', idx, 'm' 228 229 background 230 int idx 231 limit_256 232 48, ';', 5, ';', idx, 'm' 233 234 // RGB colors 235 236 foreground 237 int R, int G, int B 238 limit_256 239 38, ';', 2, ';', R, ';', G, ';', B, 'm' 240 241 background 242 int R, int G, int B 243 limit_256 244 48, ';', 2, ';', R, ';', G, ';', B, 'm' 245 246 // Set/reset text decorators 247 248 decor_set 249 Decor decor 250 | 251 (int)decor, 'm' 252 253 decor_reset 254 Decor decor 255 | 256 (int)decor + 20, 'm' 257 258 // Save/restore cursor position; 259 260 cursor_save 261 | 262 | 263 's' 264 265 cursor_restore 266 | 267 | 268 'u' 269 270 // Set screen modes 271 272 screen_mode_set 273 int n 274 limit_pos 275 '=', n, 'h' 276 277 screen_mode_reset 278 int n 279 limit_pos 280 '=', n, 'l' 281 282 // Private screen modes supported by most terminals 283 284 // Save/restore screen 285 286 screen_save 287 | 288 | 289 "?47h" 290 291 screen_restore 292 | 293 | 294 "?47l" 295 296 // Show/hide cursor 297 298 cursor_show 299 | 300 | 301 "?25h" 302 303 cursor_hide 304 | 305 | 306 "?25l" 307 308 // Enable/disable alternate buffer 309 310 abuf_enable 311 | 312 | 313 "?1049h" 314 315 abuf_disable 316 | 317 | 318 "?1049l" 319 320 // Enable/disable bracketed paste mode 321 322 paste_enable 323 | 324 | 325 "?2004h" 326 327 paste_disable 328 | 329 | 330 "?2004l" 331 332 %% 333 334 // Keyboard string TODO 335 336 } // namespace ALEC 337 338 339 #endif