1 /// Utils to work with terminal 2 module sily.terminal; 3 4 public import sily.terminal.windows; 5 public import sily.terminal.posix; 6 7 import std.stdio: stdin, stdout, File; 8 import std.process: spawnProcess, wait; 9 import std.conv: to; 10 import std.file: tempDir, remove, exists, readText; 11 import std.array: popBack; 12 13 import core.stdc.stdlib: getenv; 14 15 import sily.path: fixPath; 16 17 ColorSupport terminalColorSupport(ColorSupport defaultColor = ColorSupport.ansi8) { 18 string env = getenv("COLORTERM").to!string; 19 20 if (env == "truecolor") { 21 return ColorSupport.truecolor; 22 } else 23 if (env == "24bit") { 24 return ColorSupport.ansi256; 25 } else 26 if (env == "8bit") { 27 return ColorSupport.ansi8; 28 } 29 30 string fp = (tempDir ~ "/sily-dlang-terminal-temp.txt").fixPath(); 31 32 // TODO: rewrite with execute 33 File tf = File(fp, "w+"); 34 wait(spawnProcess(["tput", "colors"], stdin, tf)); 35 tf.close(); 36 string _out = fp.readText(); 37 if (fp.exists()) fp.remove(); 38 _out.popBack(); 39 40 if (_out == "256") return ColorSupport.ansi256; 41 if (_out == "8") return ColorSupport.ansi8; 42 43 return defaultColor; 44 } 45 46 enum ColorSupport { 47 ansi8, ansi256, truecolor 48 } 49 50 import core.stdc.stdlib: cexit = exit; 51 import core.thread: Thread; 52 import core.time: dmsecs = msecs; 53 54 /// Forcefully closes application 55 void exit(ErrorCode code = ErrorCode.general) { 56 cexit(cast(int) code); 57 } 58 59 /// Alias to ErrorCode enum 60 alias ExitCode = ErrorCode; 61 62 /// Enum containing common exit codes 63 enum ErrorCode { 64 /// Program completed correctly 65 success = 0, 66 /// Catchall for general errors (misc errors, such as `x / 0`) 67 general = 1, 68 /// Operation not permitted (missing keyword/command or permission problem) 69 noperm = 2, 70 /// Command invoked cannot execute (permission problem or command is not executable) 71 noexec = 126, 72 /// Command not found (possible problem with `$PATH` or typo) 73 notfound = 127, 74 /// Invalid argument to exit (see ErrorCode.nocode) 75 noexit = 128, 76 /// Fatal error (further execution is not possible or might harm the OS) 77 fatal = 129, 78 /// Terminated with `Ctrl-C` 79 sigint = 130, 80 /// Exit status out of range (maximal exit code) 81 nocode = 255 82 } 83 84 /// Sleeps for set amount of msecs 85 void sleep(uint msecs) { 86 Thread.sleep(msecs.dmsecs); 87 }