| ... | @@ -188,7 +188,7 @@ pub fn sync(self: File) SyncError!void { | ... | @@ -188,7 +188,7 @@ pub fn sync(self: File) SyncError!void { |
| 188 | } | 188 | } |
| 189 | | 189 | |
| 190 | /// Test whether the file refers to a terminal. | 190 | /// Test whether the file refers to a terminal. |
| 191 | /// See also `supportsAnsiEscapeCodes`. | 191 | /// See also `getOrEnableAnsiEscapeSupport` and `supportsAnsiEscapeCodes`. |
| 192 | pub fn isTty(self: File) bool { | 192 | pub fn isTty(self: File) bool { |
| 193 | return posix.isatty(self.handle); | 193 | return posix.isatty(self.handle); |
| 194 | } | 194 | } |
| ... | @@ -245,8 +245,16 @@ pub fn isCygwinPty(file: File) bool { | ... | @@ -245,8 +245,16 @@ pub fn isCygwinPty(file: File) bool { |
| 245 | std.mem.indexOf(u16, name_wide, &[_]u16{ '-', 'p', 't', 'y' }) != null; | 245 | std.mem.indexOf(u16, name_wide, &[_]u16{ '-', 'p', 't', 'y' }) != null; |
| 246 | } | 246 | } |
| 247 | | 247 | |
| 248 | /// Test whether ANSI escape codes will be treated as such. | 248 | /// Returns whether or not ANSI escape codes will be treated as such, |
| 249 | pub fn supportsAnsiEscapeCodes(self: File) bool { | 249 | /// and attempts to enable support for ANSI escape codes if necessary |
| | 250 | /// (on Windows). |
| | 251 | /// |
| | 252 | /// Returns `true` if ANSI escape codes are supported or support was |
| | 253 | /// successfully enabled. Returns false if ANSI escape codes are not |
| | 254 | /// supported or support was unable to be enabled. |
| | 255 | /// |
| | 256 | /// See also `supportsAnsiEscapeCodes`. |
| | 257 | pub fn getOrEnableAnsiEscapeSupport(self: File) bool { |
| 250 | if (builtin.os.tag == .windows) { | 258 | if (builtin.os.tag == .windows) { |
| 251 | var original_console_mode: windows.DWORD = 0; | 259 | var original_console_mode: windows.DWORD = 0; |
| 252 | | 260 | |
| ... | @@ -262,7 +270,8 @@ pub fn supportsAnsiEscapeCodes(self: File) bool { | ... | @@ -262,7 +270,8 @@ pub fn supportsAnsiEscapeCodes(self: File) bool { |
| 262 | var console_mode = original_console_mode | requested_console_modes; | 270 | var console_mode = original_console_mode | requested_console_modes; |
| 263 | if (windows.kernel32.SetConsoleMode(self.handle, console_mode) != 0) return true; | 271 | if (windows.kernel32.SetConsoleMode(self.handle, console_mode) != 0) return true; |
| 264 | | 272 | |
| 265 | // An application receiving ERROR_INVALID_PARAMETER with one of the newer console mode flags in the bit field should gracefully degrade behavior and try again. | 273 | // An application receiving ERROR_INVALID_PARAMETER with one of the newer console mode |
| | 274 | // flags in the bit field should gracefully degrade behavior and try again. |
| 266 | requested_console_modes = windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING; | 275 | requested_console_modes = windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING; |
| 267 | console_mode = original_console_mode | requested_console_modes; | 276 | console_mode = original_console_mode | requested_console_modes; |
| 268 | if (windows.kernel32.SetConsoleMode(self.handle, console_mode) != 0) return true; | 277 | if (windows.kernel32.SetConsoleMode(self.handle, console_mode) != 0) return true; |
| ... | @@ -270,6 +279,22 @@ pub fn supportsAnsiEscapeCodes(self: File) bool { | ... | @@ -270,6 +279,22 @@ pub fn supportsAnsiEscapeCodes(self: File) bool { |
| 270 | | 279 | |
| 271 | return self.isCygwinPty(); | 280 | return self.isCygwinPty(); |
| 272 | } | 281 | } |
| | 282 | return self.supportsAnsiEscapeCodes(); |
| | 283 | } |
| | 284 | |
| | 285 | /// Test whether ANSI escape codes will be treated as such without |
| | 286 | /// attempting to enable support for ANSI escape codes. |
| | 287 | /// |
| | 288 | /// See also `getOrEnableAnsiEscapeSupport`. |
| | 289 | pub fn supportsAnsiEscapeCodes(self: File) bool { |
| | 290 | if (builtin.os.tag == .windows) { |
| | 291 | var console_mode: windows.DWORD = 0; |
| | 292 | if (windows.kernel32.GetConsoleMode(self.handle, &console_mode) != 0) { |
| | 293 | if (console_mode & windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != 0) return true; |
| | 294 | } |
| | 295 | |
| | 296 | return self.isCygwinPty(); |
| | 297 | } |
| 273 | if (builtin.os.tag == .wasi) { | 298 | if (builtin.os.tag == .wasi) { |
| 274 | // WASI sanitizes stdout when fd is a tty so ANSI escape codes | 299 | // WASI sanitizes stdout when fd is a tty so ANSI escape codes |
| 275 | // will not be interpreted as actual cursor commands, and | 300 | // will not be interpreted as actual cursor commands, and |