| ... | ... | @@ -22,6 +22,10 @@ const Progress = @This(); |
| 22 | 22 | /// not print on update() |
| 23 | 23 | terminal: ?std.fs.File = undefined, |
| 24 | 24 | |
| 25 | /// Is this a windows API terminal (note: this is not the same as being run on windows |
| 26 | /// because other terminals exist like MSYS/git-bash) |
| 27 | is_windows_terminal: bool = false, |
| 28 | |
| 25 | 29 | /// Whether the terminal supports ANSI escape codes. |
| 26 | 30 | supports_ansi_escape_codes: bool = false, |
| 27 | 31 | |
| ... | ... | @@ -143,6 +147,7 @@ pub fn start(self: *Progress, name: []const u8, estimated_total_items: usize) !* |
| 143 | 147 | self.terminal = stderr; |
| 144 | 148 | self.supports_ansi_escape_codes = true; |
| 145 | 149 | } else if (std.builtin.os.tag == .windows and stderr.isTty()) { |
| 150 | self.is_windows_terminal = true; |
| 146 | 151 | self.terminal = stderr; |
| 147 | 152 | } else if (std.builtin.os.tag != .windows) { |
| 148 | 153 | // we are in a "dumb" terminal like in acme or writing to a file |
| ... | ... | @@ -192,8 +197,9 @@ const DECRC = "\x1b8"; |
| 192 | 197 | // supported by some terminals (eg. Terminal.app). |
| 193 | 198 | |
| 194 | 199 | fn refreshWithHeldLock(self: *Progress) void { |
| 195 | | const is_dumb = !self.supports_ansi_escape_codes and !(std.builtin.os.tag == .windows); |
| 200 | const is_dumb = !self.supports_ansi_escape_codes and !self.is_windows_terminal; |
| 196 | 201 | if (is_dumb and self.dont_print_on_dumb) return; |
| 202 | |
| 197 | 203 | const file = self.terminal orelse return; |
| 198 | 204 | |
| 199 | 205 | var end: usize = 0; |
| ... | ... | @@ -206,6 +212,8 @@ fn refreshWithHeldLock(self: *Progress) void { |
| 206 | 212 | std.mem.copy(u8, self.output_buffer[end..], seq_before); |
| 207 | 213 | end += seq_before.len; |
| 208 | 214 | } else if (std.builtin.os.tag == .windows) winapi: { |
| 215 | std.debug.assert(self.is_windows_terminal); |
| 216 | |
| 209 | 217 | var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined; |
| 210 | 218 | if (windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != windows.TRUE) |
| 211 | 219 | unreachable; |
| ... | ... | @@ -282,7 +290,7 @@ fn refreshWithHeldLock(self: *Progress) void { |
| 282 | 290 | const seq_after = DECRC; |
| 283 | 291 | std.mem.copy(u8, self.output_buffer[end..], seq_after); |
| 284 | 292 | end += seq_after.len; |
| 285 | | } else if (std.builtin.os.tag != .windows) { |
| 293 | } else if (!self.is_windows_terminal) { |
| 286 | 294 | self.output_buffer[end] = '\n'; |
| 287 | 295 | end += 1; |
| 288 | 296 | } |
| ... | ... | @@ -293,8 +301,10 @@ fn refreshWithHeldLock(self: *Progress) void { |
| 293 | 301 | }; |
| 294 | 302 | |
| 295 | 303 | if (std.builtin.os.tag == .windows) { |
| 296 | | if (windows.kernel32.SetConsoleCursorPosition(file.handle, saved_cursor_pos) != windows.TRUE) |
| 297 | | unreachable; |
| 304 | if (self.is_windows_terminal) { |
| 305 | const res = windows.kernel32.SetConsoleCursorPosition(file.handle, saved_cursor_pos); |
| 306 | std.debug.assert(res == windows.TRUE); |
| 307 | } |
| 298 | 308 | } |
| 299 | 309 | |
| 300 | 310 | self.prev_refresh_timestamp = self.timer.read(); |
| ... | ... | @@ -318,7 +328,7 @@ fn bufWrite(self: *Progress, end: *usize, comptime format: []const u8, args: any |
| 318 | 328 | end.* = self.output_buffer.len; |
| 319 | 329 | }, |
| 320 | 330 | } |
| 321 | | const bytes_needed_for_esc_codes_at_end = if (std.builtin.os.tag == .windows) 0 else 11; |
| 331 | const bytes_needed_for_esc_codes_at_end: u8 = if (self.is_windows_terminal) 0 else 11; |
| 322 | 332 | const max_end = self.output_buffer.len - bytes_needed_for_esc_codes_at_end; |
| 323 | 333 | if (end.* > max_end) { |
| 324 | 334 | const suffix = "... "; |