alec

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

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