| ... | @@ -218,6 +218,7 @@ pub const Environ = struct { | ... | @@ -218,6 +218,7 @@ pub const Environ = struct { |
| 218 | DEBUGINFOD_CACHE_PATH: ?[:0]const u8 = null, | 218 | DEBUGINFOD_CACHE_PATH: ?[:0]const u8 = null, |
| 219 | XDG_CACHE_HOME: ?[:0]const u8 = null, | 219 | XDG_CACHE_HOME: ?[:0]const u8 = null, |
| 220 | HOME: ?[:0]const u8 = null, | 220 | HOME: ?[:0]const u8 = null, |
| | 221 | TERM: ?[:0]const u8 = null, |
| 221 | }, | 222 | }, |
| 222 | }; | 223 | }; |
| 223 | | 224 | |
| ... | @@ -8800,9 +8801,8 @@ fn isTty(file: File) Io.Cancelable!bool { | ... | @@ -8800,9 +8801,8 @@ fn isTty(file: File) Io.Cancelable!bool { |
| 8800 | | 8801 | |
| 8801 | fn fileEnableAnsiEscapeCodes(userdata: ?*anyopaque, file: File) File.EnableAnsiEscapeCodesError!void { | 8802 | fn fileEnableAnsiEscapeCodes(userdata: ?*anyopaque, file: File) File.EnableAnsiEscapeCodesError!void { |
| 8802 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 8803 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 8803 | _ = t; | | |
| 8804 | | 8804 | |
| 8805 | if (!is_windows) return if (!try supportsAnsiEscapeCodes(file)) error.NotTerminalDevice; | 8805 | if (!is_windows) return if (!try supportsAnsiEscapeCodes(t, file)) error.NotTerminalDevice; |
| 8806 | | 8806 | |
| 8807 | // For Windows Terminal, VT Sequences processing is enabled by default. | 8807 | // For Windows Terminal, VT Sequences processing is enabled by default. |
| 8808 | const console: File = .{ | 8808 | const console: File = .{ |
| ... | @@ -8850,14 +8850,13 @@ fn fileEnableAnsiEscapeCodes(userdata: ?*anyopaque, file: File) File.EnableAnsiE | ... | @@ -8850,14 +8850,13 @@ fn fileEnableAnsiEscapeCodes(userdata: ?*anyopaque, file: File) File.EnableAnsiE |
| 8850 | | 8850 | |
| 8851 | fn fileSupportsAnsiEscapeCodes(userdata: ?*anyopaque, file: File) Io.Cancelable!bool { | 8851 | fn fileSupportsAnsiEscapeCodes(userdata: ?*anyopaque, file: File) Io.Cancelable!bool { |
| 8852 | const t: *Threaded = @ptrCast(@alignCast(userdata)); | 8852 | const t: *Threaded = @ptrCast(@alignCast(userdata)); |
| 8853 | _ = t; | 8853 | return supportsAnsiEscapeCodes(t, file); |
| 8854 | return supportsAnsiEscapeCodes(file); | | |
| 8855 | } | 8854 | } |
| 8856 | | 8855 | |
| 8857 | fn supportsAnsiEscapeCodes(file: File) Io.Cancelable!bool { | 8856 | fn supportsAnsiEscapeCodes(t: *Threaded, file: File) Io.Cancelable!bool { |
| 8858 | if (is_windows) { | 8857 | if (is_windows) { |
| 8859 | var get_console_mode = windows.CONSOLE.USER_IO.GET_MODE; | 8858 | var get_console_mode = windows.CONSOLE.USER_IO.GET_MODE; |
| 8860 | switch ((try deviceIoControl(&.{ | 8859 | return switch ((try deviceIoControl(&.{ |
| 8861 | .file = .{ | 8860 | .file = .{ |
| 8862 | .handle = windows.peb().ProcessParameters.ConsoleHandle, | 8861 | .handle = windows.peb().ProcessParameters.ConsoleHandle, |
| 8863 | .flags = .{ .nonblocking = false }, | 8862 | .flags = .{ .nonblocking = false }, |
| ... | @@ -8865,15 +8864,33 @@ fn supportsAnsiEscapeCodes(file: File) Io.Cancelable!bool { | ... | @@ -8865,15 +8864,33 @@ fn supportsAnsiEscapeCodes(file: File) Io.Cancelable!bool { |
| 8865 | .code = windows.IOCTL.CONDRV.ISSUE_USER_IO, | 8864 | .code = windows.IOCTL.CONDRV.ISSUE_USER_IO, |
| 8866 | .in = @ptrCast(&get_console_mode.request(file, 0, .{}, 0, .{})), | 8865 | .in = @ptrCast(&get_console_mode.request(file, 0, .{}, 0, .{})), |
| 8867 | })).u.Status) { | 8866 | })).u.Status) { |
| 8868 | .SUCCESS => if (get_console_mode.Data & windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != 0) | 8867 | .SUCCESS => get_console_mode.Data & windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != 0, |
| 8869 | return true, | | |
| 8870 | .CANCELLED => unreachable, | 8868 | .CANCELLED => unreachable, |
| 8871 | .INVALID_HANDLE => return isCygwinPty(file), | 8869 | .INVALID_HANDLE => isCygwinPty(file), |
| 8872 | else => return false, | 8870 | else => false, |
| 8873 | } | 8871 | }; |
| 8874 | } | 8872 | } |
| 8875 | | 8873 | |
| 8876 | if (try isTty(file)) return true; | 8874 | if (native_os == .wasi) { |
| | 8875 | // WASI sanitizes stdout when fd is a tty so ANSI escape codes |
| | 8876 | // will not be interpreted as actual cursor commands, and |
| | 8877 | // stderr is always sanitized. |
| | 8878 | |
| | 8879 | return false; |
| | 8880 | } |
| | 8881 | |
| | 8882 | if (try isTty(file)) { |
| | 8883 | if (file.handle == posix.STDOUT_FILENO or file.handle == posix.STDERR_FILENO) { |
| | 8884 | t.scanEnviron(); |
| | 8885 | if (t.environ.string.TERM) |term| { |
| | 8886 | if (std.mem.eql(u8, term, "dumb")) { |
| | 8887 | return false; |
| | 8888 | } |
| | 8889 | } |
| | 8890 | } |
| | 8891 | |
| | 8892 | return true; |
| | 8893 | } |
| 8877 | | 8894 | |
| 8878 | return false; | 8895 | return false; |
| 8879 | } | 8896 | } |