1 module sily.bashfmt; 2 3 import std.conv : to; 4 import std.stdio : write, writef; 5 6 static this() { 7 version(windows) { 8 import core.stdc.stdlib: exit; 9 exit(2); 10 } 11 } 12 13 14 alias FG = Foreground; 15 alias BG = Background; 16 alias FM = Formatting; 17 alias FR = FormattingReset; 18 19 enum Foreground : string { 20 reset = "\033[39m", 21 black = "\033[30m", 22 red = "\033[31m", 23 green = "\033[32m", 24 yellow = "\033[33m", 25 blue = "\033[34m", 26 magenta = "\033[35m", 27 cyan = "\033[36m", 28 ltgray = "\033[37m", 29 dkgray = "\033[90m", 30 ltred = "\033[91m", 31 ltgreen = "\033[92m", 32 ltyellow = "\033[93m", 33 ltblue = "\033[94m", 34 ltmagenta = "\033[95m", 35 ltcyan = "\033[96m", 36 white = "\033[97m", 37 } 38 39 enum Background : string { 40 reset = "\033[49m", 41 black = "\033[40m", 42 red = "\033[41m", 43 green = "\033[42m", 44 yellow = "\033[43m", 45 blue = "\033[44m", 46 magenta = "\033[45m", 47 cyan = "\033[46m", 48 ltgray = "\033[47m", 49 dkgray = "\033[100m", 50 ltred = "\033[101m", 51 ltgreen = "\033[102m", 52 ltyellow = "\033[103m", 53 ltblue = "\033[104m", 54 ltmagenta = "\033[105m", 55 ltcyan = "\033[106m", 56 white = "\033[107m" 57 } 58 59 enum Formatting : string { 60 bold = "\033[1m", 61 dim = "\033[2m", 62 italics = "\033[3m", 63 uline = "\033[4m", 64 blink = "\033[5m", 65 inverse = "\033[7m", 66 hidden = "\033[8m", 67 striked = "\033[9m", 68 dline = "\033[21m", 69 cline = "\033[4:3m", 70 oline = "\033[53" 71 } 72 73 enum FormattingReset : string { 74 reset = "\033[0m", 75 fullreset = "\033[m", 76 77 bold = "\033[21m", 78 dim = "\033[22m", 79 italics = "\033[22m", 80 uline = "\033[24m", 81 blink = "\033[25m", 82 inverse = "\033[27m", 83 hidden = "\033[28m", 84 striked = "\033[29m", 85 dline = "\033[24m", 86 cline = "\033[4:0m", 87 oline = "\033[55m" 88 } 89 90 /** 91 * Casts args to string and writes to stdout 92 * 93 * Intended to be used to print formatting 94 * --- 95 * fwrite("White text", FG.red, "Red text", FG.reset, BG.red, "Red background", FR.fullreset); 96 * --- 97 * Params: 98 * args = Text or one of formatting strings 99 */ 100 void fwrite(A...)(A args) { 101 foreach (arg; args) { 102 write(cast(string) arg); 103 } 104 } 105 106 /** 107 * Casts args to string and writes to stdout with `\n` at the end 108 * 109 * Intended to be used to print formatting 110 * --- 111 * fwriteln("White text", FG.red, "Red text", FG.reset, BG.red, "Red background", FR.fullreset); 112 * --- 113 * Params: 114 * args = Text or one of formatting strings 115 */ 116 void fwriteln(A...)(A args) { 117 foreach (arg; args) { 118 write(cast(string) arg); 119 } 120 write("\n"); 121 } 122 123 /** 124 * Erases `num` lines in terminal starting with current. 125 * Params: 126 * num = Number of lines to erase 127 */ 128 void eraseLines(int num) { 129 eraseCurrentLine(); 130 --num; 131 132 while (num) { 133 moveCursorUp(1); 134 eraseCurrentLine(); 135 --num; 136 } 137 } 138 139 /** 140 * Moves cursor in terminal to `{x, y}` 141 * Params: 142 * x = Column to move to 143 * y = Row to move to 144 */ 145 void moveCursorTo(int x, int y) { 146 writef("\033[%d;%df", x, y); 147 } 148 149 /** 150 * Moves cursor in terminal up by `lineAmount` 151 * Params: 152 * lineAmount = int 153 */ 154 void moveCursorUp(int lineAmount = 1) { 155 writef("\033[%dA", lineAmount); 156 } 157 158 /** 159 * Moves cursor in terminal down by `lineAmount` 160 * Params: 161 * lineAmount = int 162 */ 163 void moveCursorDown(int lineAmount = 1) { 164 writef("\033[%dB", lineAmount); 165 } 166 167 /** 168 * Moves cursor in terminal right by `columnAmount` 169 * Params: 170 * columnAmount = int 171 */ 172 void moveCursorRight(int columnAmount = 1) { 173 writef("\033[%dC", columnAmount); 174 } 175 176 /** 177 * Moves cursor in terminal left by `columnAmount` 178 * Params: 179 * columnAmount = int 180 */ 181 void moveCursorLeft(int columnAmount = 1) { 182 writef("\033[%dD", columnAmount); 183 } 184 185 /** 186 * Clears terminal screen and resets cursor position 187 */ 188 void clearScreen() { 189 write("\033[2J"); 190 moveCursorTo(0, 0); 191 } 192 193 /** 194 * Clears terminal screen 195 */ 196 void clearScreenOnly() { 197 write("\033[2J"); 198 } 199 200 /** 201 * Fully erases current line 202 */ 203 void eraseCurrentLine() { 204 write("\033[2K"); 205 } 206 207 /** 208 * Erases text from start of current line to cursor 209 */ 210 void eraseLineLeft() { 211 write("\033[1K"); 212 } 213 214 /** 215 * Erases text from cursor to end of current line 216 */ 217 void eraseLineRight() { 218 write("\033[K"); 219 } 220 221 /** 222 * Saves cursor position to be restored later 223 */ 224 void saveCursorPosition() { 225 write("\033[s"); 226 } 227 228 /** 229 * Restores saved cursor position (moves cursor to saved pos) 230 */ 231 void restoreCursorPosition() { 232 write("\033[u"); 233 } 234 235 /** 236 * Hides cursor. Does not reset position 237 */ 238 void hideCursor() { 239 write("\033[?25l"); 240 } 241 242 /** 243 * Shows cursor. Does not reset position 244 */ 245 void showCursor() { 246 write("\033[?25h"); 247 } 248 249 /** 250 * Intended to be used in SIGINT callback 251 * 252 * Resets all formatting and shows cursor 253 */ 254 void cleanTerminalState() nothrow @nogc @system { 255 import core.stdc.stdio: printf; 256 printf("\033[?25h\033[m"); 257 }