1 /++ 2 Windows specific terminal utils. Made only to handle unicode page and get terminal size. 3 It is not in any means stable or finished or should be used in production. 4 Please just use linux, it's so much better in that regard 5 +/ 6 module sily.terminal.windows; 7 8 version(Windows): 9 10 static this() { 11 // To prevent from killing terminal by calling reset before set 12 GetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), &originalMode); 13 14 import core.sys.windows.windows : SetConsoleOutputCP; 15 SetConsoleOutputCP(65_001); 16 } 17 18 /* ------------------------------ TERMINAL SIZE ----------------------------- */ 19 20 import core.sys.windows.windows; 21 22 /// Returns bash terminal width 23 int terminalWidth() { 24 CONSOLE_SCREEN_BUFFER_INFO csbi; 25 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); 26 return csbi.srWindow.Bottom - csbi.srWindow.Top + 1; 27 } 28 29 /// Returns bash terminal height 30 int terminalHeight() { 31 CONSOLE_SCREEN_BUFFER_INFO csbi; 32 GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi); 33 return csbi.srWindow.Right - csbi.srWindow.Left + 1; 34 } 35 36 /* -------------------------------- RAW MODE -------------------------------- */ 37 import core.stdc.stdio: setvbuf, _IONBF, _IOLBF; 38 import core.stdc.stdlib: atexit; 39 import core.stdc.string: memcpy; 40 41 import std.stdio: stdin, stdout, File; 42 43 private uint originalMode; 44 45 private bool __isTermiosRaw = false; 46 47 /// Is terminal in raw mode (have `setTerminalModeRaw` been called yet?) 48 bool isTerminalRaw() nothrow { 49 // HANDLE h = GetStdHandle(STD_INPUT_HANDLE); 50 // uint mr = ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT; 51 // uint mc; 52 // GetConsoleMode(h, &mc); 53 // return !(mc & mr); 54 return false; 55 } 56 57 /// Resets termios back to default and buffers stdout 58 extern(C) alias terminalModeReset = function() { 59 HANDLE h = GetStdHandle(STD_INPUT_HANDLE); 60 SetConsoleMode(h, originalMode); 61 __isTermiosRaw = false; 62 }; 63 64 /** 65 Creates new termios and unbuffers stdout. Required for `kbhit` and `getch` 66 DO NOT USE IF YOU DON'T KNOW WHAT YOU'RE DOING 67 68 Note that in raw mode CRLF (`\r\n`) newline will be 69 required instead of normal LF (`\n`) 70 Params: 71 removeStdoutBuffer = Does nothing on windows 72 */ 73 void terminalModeSetRaw(bool removeStdoutBuffer = true) { 74 // HANDLE h = GetStdHandle(STD_INPUT_HANDLE); 75 // uint mr = originalMode; 76 // mr &= ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_INSERT_MODE ; 77 // SetConsoleMode(h, mr); 78 79 // atexit(terminalModeReset); 80 // __isTermiosRaw = true; 81 } 82 83 /// Returns true if any key was pressed 84 bool kbhit() { 85 // HANDLE stdIn = GetStdHandle(STD_INPUT_HANDLE); 86 // DWORD saveMode; 87 88 // GetConsoleMode(stdIn, &saveMode); 89 // SetConsoleMode(stdIn, ENABLE_PROCESSED_INPUT); 90 91 // bool ret = false; 92 93 // if (WaitForSingleObject(stdIn, INFINITE) == WAIT_OBJECT_0) { 94 // uint num; 95 // char ch; 96 97 // ReadConsoleA(stdIn, &ch, 1, &num, cast(void *) 0L); 98 // ret = true; 99 // } 100 101 // SetConsoleMode(stdIn, saveMode); 102 // return ret; 103 return false; 104 } 105 106 /// Returns last pressed key 107 int getch() { 108 // int r; 109 // uint c; 110 // stdin.readf!"%d"(r); 111 // if (r < 0) { 112 // return r; 113 // } else { 114 // return c; 115 // } 116 return 0; 117 } 118 119 /* ---------------------------------- MISC ---------------------------------- */ 120 // import core.sys.posix.unistd: posixIsATTY = isatty; 121 // import std.stdio: File; 122 import core.stdc.stdio: FILE, cfileno = fileno; 123 import core.stdc.errno; 124 125 /// Returns true if file is a tty (can't promice it'll work on windows properly) 126 bool isatty(File file) { 127 return false; 128 // return cast(bool) posixIsATTY(file.fileno); 129 } 130 /// Ditto 131 bool isatty(FILE* handle) { 132 return false; 133 // return cast(bool) posixIsATTY(handle.cfileno); 134 } 135 /// Ditto 136 bool isatty(int fd_set) { 137 return false; 138 // return cast(bool) posixIsATTY(fd_set); 139 }