| author | |
| committer | |
| log | d8b4588d5fe685637ebbbb57c139aca7fb12ddf5 |
| tree | 79256623488e292cff4d5cb9f7e08664727413dc |
| parent | 8691fde0f631daf527a4e030d0be9d26c5b16208 |
4 files changed, 71 insertions(+), 82 deletions(-)
lib/std/Progress.zig+17-8| ... | @@ -210,8 +210,11 @@ fn refreshWithHeldLock(self: *Progress) void { | ... | @@ -210,8 +210,11 @@ fn refreshWithHeldLock(self: *Progress) void { |
| 210 | std.debug.assert(self.is_windows_terminal); | 210 | std.debug.assert(self.is_windows_terminal); |
| 211 | 211 | ||
| 212 | var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined; | 212 | var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined; |
| 213 | if (windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != windows.TRUE) | 213 | if (windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != windows.TRUE) { |
| 214 | unreachable; | 214 | // stop trying to write to this file |
| 215 | self.terminal = null; | ||
| 216 | break :winapi; | ||
| 217 | } | ||
| 215 | 218 | ||
| 216 | var cursor_pos = windows.COORD{ | 219 | var cursor_pos = windows.COORD{ |
| 217 | .X = info.dwCursorPosition.X - @intCast(windows.SHORT, self.columns_written), | 220 | .X = info.dwCursorPosition.X - @intCast(windows.SHORT, self.columns_written), |
| ... | @@ -231,7 +234,7 @@ fn refreshWithHeldLock(self: *Progress) void { | ... | @@ -231,7 +234,7 @@ fn refreshWithHeldLock(self: *Progress) void { |
| 231 | cursor_pos, | 234 | cursor_pos, |
| 232 | &written, | 235 | &written, |
| 233 | ) != windows.TRUE) { | 236 | ) != windows.TRUE) { |
| 234 | // Stop trying to write to this file. | 237 | // stop trying to write to this file |
| 235 | self.terminal = null; | 238 | self.terminal = null; |
| 236 | break :winapi; | 239 | break :winapi; |
| 237 | } | 240 | } |
| ... | @@ -241,10 +244,16 @@ fn refreshWithHeldLock(self: *Progress) void { | ... | @@ -241,10 +244,16 @@ fn refreshWithHeldLock(self: *Progress) void { |
| 241 | fill_chars, | 244 | fill_chars, |
| 242 | cursor_pos, | 245 | cursor_pos, |
| 243 | &written, | 246 | &written, |
| 244 | ) != windows.TRUE) unreachable; | 247 | ) != windows.TRUE) { |
| 245 | 248 | // stop trying to write to this file | |
| 246 | if (windows.kernel32.SetConsoleCursorPosition(file.handle, cursor_pos) != windows.TRUE) | 249 | self.terminal = null; |
| 247 | unreachable; | 250 | break :winapi; |
| 251 | } | ||
| 252 | if (windows.kernel32.SetConsoleCursorPosition(file.handle, cursor_pos) != windows.TRUE) { | ||
| 253 | // stop trying to write to this file | ||
| 254 | self.terminal = null; | ||
| 255 | break :winapi; | ||
| 256 | } | ||
| 248 | } else { | 257 | } else { |
| 249 | // we are in a "dumb" terminal like in acme or writing to a file | 258 | // we are in a "dumb" terminal like in acme or writing to a file |
| 250 | self.output_buffer[end] = '\n'; | 259 | self.output_buffer[end] = '\n'; |
| ... | @@ -288,7 +297,7 @@ fn refreshWithHeldLock(self: *Progress) void { | ... | @@ -288,7 +297,7 @@ fn refreshWithHeldLock(self: *Progress) void { |
| 288 | } | 297 | } |
| 289 | 298 | ||
| 290 | _ = file.write(self.output_buffer[0..end]) catch { | 299 | _ = file.write(self.output_buffer[0..end]) catch { |
| 291 | // Stop trying to write to this file once it errors. | 300 | // stop trying to write to this file |
| 292 | self.terminal = null; | 301 | self.terminal = null; |
| 293 | }; | 302 | }; |
| 294 | if (self.timer) |*timer| { | 303 | if (self.timer) |*timer| { |
lib/std/debug.zig+35-55| ... | @@ -119,7 +119,7 @@ pub fn detectTTYConfig() TTY.Config { | ... | @@ -119,7 +119,7 @@ pub fn detectTTYConfig() TTY.Config { |
| 119 | if (stderr_file.supportsAnsiEscapeCodes()) { | 119 | if (stderr_file.supportsAnsiEscapeCodes()) { |
| 120 | return .escape_codes; | 120 | return .escape_codes; |
| 121 | } else if (native_os == .windows and stderr_file.isTty()) { | 121 | } else if (native_os == .windows and stderr_file.isTty()) { |
| 122 | return .windows_api; | 122 | return .{ .windows_api = stderr_file }; |
| 123 | } else { | 123 | } else { |
| 124 | return .no_color; | 124 | return .no_color; |
| 125 | } | 125 | } |
| ... | @@ -415,9 +415,9 @@ pub fn writeStackTrace( | ... | @@ -415,9 +415,9 @@ pub fn writeStackTrace( |
| 415 | if (stack_trace.index > stack_trace.instruction_addresses.len) { | 415 | if (stack_trace.index > stack_trace.instruction_addresses.len) { |
| 416 | const dropped_frames = stack_trace.index - stack_trace.instruction_addresses.len; | 416 | const dropped_frames = stack_trace.index - stack_trace.instruction_addresses.len; |
| 417 | 417 | ||
| 418 | tty_config.setColor(out_stream, .Bold); | 418 | tty_config.setColor(out_stream, .Bold) catch {}; |
| 419 | try out_stream.print("({d} additional stack frames skipped...)\n", .{dropped_frames}); | 419 | try out_stream.print("({d} additional stack frames skipped...)\n", .{dropped_frames}); |
| 420 | tty_config.setColor(out_stream, .Reset); | 420 | tty_config.setColor(out_stream, .Reset) catch {}; |
| 421 | } | 421 | } |
| 422 | } | 422 | } |
| 423 | 423 | ||
| ... | @@ -605,59 +605,39 @@ pub const TTY = struct { | ... | @@ -605,59 +605,39 @@ pub const TTY = struct { |
| 605 | Reset, | 605 | Reset, |
| 606 | }; | 606 | }; |
| 607 | 607 | ||
| 608 | pub const Config = enum { | 608 | pub const Config = union(enum) { |
| 609 | no_color, | 609 | no_color, |
| 610 | escape_codes, | 610 | escape_codes, |
| 611 | // TODO give this a payload of file handle | 611 | windows_api: File, |
| 612 | windows_api, | ||
| 613 | 612 | ||
| 614 | pub fn setColor(conf: Config, out_stream: anytype, color: Color) void { | 613 | pub fn setColor(conf: Config, out_stream: anytype, color: Color) !void { |
| 615 | nosuspend switch (conf) { | 614 | nosuspend switch (conf) { |
| 616 | .no_color => return, | 615 | .no_color => return, |
| 617 | .escape_codes => switch (color) { | 616 | .escape_codes => { |
| 618 | .Red => out_stream.writeAll(RED) catch return, | 617 | const color_string = switch (color) { |
| 619 | .Green => out_stream.writeAll(GREEN) catch return, | 618 | .Red => RED, |
| 620 | .Cyan => out_stream.writeAll(CYAN) catch return, | 619 | .Green => GREEN, |
| 621 | .White => out_stream.writeAll(WHITE) catch return, | 620 | .Cyan => CYAN, |
| 622 | .Dim => out_stream.writeAll(DIM) catch return, | 621 | .White => WHITE, |
| 623 | .Bold => out_stream.writeAll(BOLD) catch return, | 622 | .Dim => DIM, |
| 624 | .Reset => out_stream.writeAll(RESET) catch return, | 623 | .Bold => BOLD, |
| 624 | .Reset => RESET, | ||
| 625 | }; | ||
| 626 | try out_stream.writeAll(color_string); | ||
| 625 | }, | 627 | }, |
| 626 | .windows_api => if (native_os == .windows) { | 628 | .windows_api => |file| if (native_os == .windows) { |
| 627 | const stderr_file = io.getStdErr(); | 629 | var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined; |
| 628 | const S = struct { | 630 | if (windows.kernel32.GetConsoleScreenBufferInfo(file.handle, &info) != windows.TRUE) |
| 629 | var attrs: windows.WORD = undefined; | 631 | return error.FailedRetrievingTerminalInfo; |
| 630 | var init_attrs = false; | 632 | const attributes = switch (color) { |
| 633 | .Red => windows.FOREGROUND_RED | windows.FOREGROUND_INTENSITY, | ||
| 634 | .Green => windows.FOREGROUND_GREEN | windows.FOREGROUND_INTENSITY, | ||
| 635 | .Cyan => windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY, | ||
| 636 | .White, .Bold => windows.FOREGROUND_RED | windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY, | ||
| 637 | .Dim => windows.FOREGROUND_INTENSITY, | ||
| 638 | .Reset => info.wAttributes, | ||
| 631 | }; | 639 | }; |
| 632 | if (!S.init_attrs) { | 640 | try windows.SetConsoleTextAttribute(file.handle, attributes); |
| 633 | S.init_attrs = true; | ||
| 634 | var info: windows.CONSOLE_SCREEN_BUFFER_INFO = undefined; | ||
| 635 | // TODO handle error | ||
| 636 | _ = windows.kernel32.GetConsoleScreenBufferInfo(stderr_file.handle, &info); | ||
| 637 | S.attrs = info.wAttributes; | ||
| 638 | } | ||
| 639 | |||
| 640 | // TODO handle errors | ||
| 641 | switch (color) { | ||
| 642 | .Red => { | ||
| 643 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_INTENSITY) catch {}; | ||
| 644 | }, | ||
| 645 | .Green => { | ||
| 646 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_GREEN | windows.FOREGROUND_INTENSITY) catch {}; | ||
| 647 | }, | ||
| 648 | .Cyan => { | ||
| 649 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {}; | ||
| 650 | }, | ||
| 651 | .White, .Bold => { | ||
| 652 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_RED | windows.FOREGROUND_GREEN | windows.FOREGROUND_BLUE | windows.FOREGROUND_INTENSITY) catch {}; | ||
| 653 | }, | ||
| 654 | .Dim => { | ||
| 655 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, windows.FOREGROUND_INTENSITY) catch {}; | ||
| 656 | }, | ||
| 657 | .Reset => { | ||
| 658 | _ = windows.SetConsoleTextAttribute(stderr_file.handle, S.attrs) catch {}; | ||
| 659 | }, | ||
| 660 | } | ||
| 661 | } else { | 641 | } else { |
| 662 | unreachable; | 642 | unreachable; |
| 663 | }, | 643 | }, |
| ... | @@ -751,7 +731,7 @@ fn printLineInfo( | ... | @@ -751,7 +731,7 @@ fn printLineInfo( |
| 751 | comptime printLineFromFile: anytype, | 731 | comptime printLineFromFile: anytype, |
| 752 | ) !void { | 732 | ) !void { |
| 753 | nosuspend { | 733 | nosuspend { |
| 754 | tty_config.setColor(out_stream, .Bold); | 734 | try tty_config.setColor(out_stream, .Bold); |
| 755 | 735 | ||
| 756 | if (line_info) |*li| { | 736 | if (line_info) |*li| { |
| 757 | try out_stream.print("{s}:{d}:{d}", .{ li.file_name, li.line, li.column }); | 737 | try out_stream.print("{s}:{d}:{d}", .{ li.file_name, li.line, li.column }); |
| ... | @@ -759,11 +739,11 @@ fn printLineInfo( | ... | @@ -759,11 +739,11 @@ fn printLineInfo( |
| 759 | try out_stream.writeAll("???:?:?"); | 739 | try out_stream.writeAll("???:?:?"); |
| 760 | } | 740 | } |
| 761 | 741 | ||
| 762 | tty_config.setColor(out_stream, .Reset); | 742 | try tty_config.setColor(out_stream, .Reset); |
| 763 | try out_stream.writeAll(": "); | 743 | try out_stream.writeAll(": "); |
| 764 | tty_config.setColor(out_stream, .Dim); | 744 | try tty_config.setColor(out_stream, .Dim); |
| 765 | try out_stream.print("0x{x} in {s} ({s})", .{ address, symbol_name, compile_unit_name }); | 745 | try out_stream.print("0x{x} in {s} ({s})", .{ address, symbol_name, compile_unit_name }); |
| 766 | tty_config.setColor(out_stream, .Reset); | 746 | try tty_config.setColor(out_stream, .Reset); |
| 767 | try out_stream.writeAll("\n"); | 747 | try out_stream.writeAll("\n"); |
| 768 | 748 | ||
| 769 | // Show the matching source code line if possible | 749 | // Show the matching source code line if possible |
| ... | @@ -774,9 +754,9 @@ fn printLineInfo( | ... | @@ -774,9 +754,9 @@ fn printLineInfo( |
| 774 | const space_needed = @intCast(usize, li.column - 1); | 754 | const space_needed = @intCast(usize, li.column - 1); |
| 775 | 755 | ||
| 776 | try out_stream.writeByteNTimes(' ', space_needed); | 756 | try out_stream.writeByteNTimes(' ', space_needed); |
| 777 | tty_config.setColor(out_stream, .Green); | 757 | try tty_config.setColor(out_stream, .Green); |
| 778 | try out_stream.writeAll("^"); | 758 | try out_stream.writeAll("^"); |
| 779 | tty_config.setColor(out_stream, .Reset); | 759 | try tty_config.setColor(out_stream, .Reset); |
| 780 | } | 760 | } |
| 781 | try out_stream.writeAll("\n"); | 761 | try out_stream.writeAll("\n"); |
| 782 | } else |err| switch (err) { | 762 | } else |err| switch (err) { |
lib/std/testing.zig+4-4| ... | @@ -387,9 +387,9 @@ fn SliceDiffer(comptime T: type) type { | ... | @@ -387,9 +387,9 @@ fn SliceDiffer(comptime T: type) type { |
| 387 | for (self.expected) |value, i| { | 387 | for (self.expected) |value, i| { |
| 388 | var full_index = self.start_index + i; | 388 | var full_index = self.start_index + i; |
| 389 | const diff = if (i < self.actual.len) !std.meta.eql(self.actual[i], value) else true; | 389 | const diff = if (i < self.actual.len) !std.meta.eql(self.actual[i], value) else true; |
| 390 | if (diff) self.ttyconf.setColor(writer, .Red); | 390 | if (diff) try self.ttyconf.setColor(writer, .Red); |
| 391 | try writer.print("[{}]: {any}\n", .{ full_index, value }); | 391 | try writer.print("[{}]: {any}\n", .{ full_index, value }); |
| 392 | if (diff) self.ttyconf.setColor(writer, .Reset); | 392 | if (diff) try self.ttyconf.setColor(writer, .Reset); |
| 393 | } | 393 | } |
| 394 | } | 394 | } |
| 395 | }; | 395 | }; |
| ... | @@ -427,9 +427,9 @@ const BytesDiffer = struct { | ... | @@ -427,9 +427,9 @@ const BytesDiffer = struct { |
| 427 | } | 427 | } |
| 428 | 428 | ||
| 429 | fn writeByteDiff(self: BytesDiffer, writer: anytype, comptime fmt: []const u8, byte: u8, diff: bool) !void { | 429 | fn writeByteDiff(self: BytesDiffer, writer: anytype, comptime fmt: []const u8, byte: u8, diff: bool) !void { |
| 430 | if (diff) self.ttyconf.setColor(writer, .Red); | 430 | if (diff) try self.ttyconf.setColor(writer, .Red); |
| 431 | try writer.print(fmt, .{byte}); | 431 | try writer.print(fmt, .{byte}); |
| 432 | if (diff) self.ttyconf.setColor(writer, .Reset); | 432 | if (diff) try self.ttyconf.setColor(writer, .Reset); |
| 433 | } | 433 | } |
| 434 | 434 | ||
| 435 | const ChunkIterator = struct { | 435 | const ChunkIterator = struct { |
src/Compilation.zig+15-15| ... | @@ -428,29 +428,29 @@ pub const AllErrors = struct { | ... | @@ -428,29 +428,29 @@ pub const AllErrors = struct { |
| 428 | switch (msg) { | 428 | switch (msg) { |
| 429 | .src => |src| { | 429 | .src => |src| { |
| 430 | try counting_stderr.writeByteNTimes(' ', indent); | 430 | try counting_stderr.writeByteNTimes(' ', indent); |
| 431 | ttyconf.setColor(stderr, .Bold); | 431 | try ttyconf.setColor(stderr, .Bold); |
| 432 | try counting_stderr.print("{s}:{d}:{d}: ", .{ | 432 | try counting_stderr.print("{s}:{d}:{d}: ", .{ |
| 433 | src.src_path, | 433 | src.src_path, |
| 434 | src.line + 1, | 434 | src.line + 1, |
| 435 | src.column + 1, | 435 | src.column + 1, |
| 436 | }); | 436 | }); |
| 437 | ttyconf.setColor(stderr, color); | 437 | try ttyconf.setColor(stderr, color); |
| 438 | try counting_stderr.writeAll(kind); | 438 | try counting_stderr.writeAll(kind); |
| 439 | try counting_stderr.writeAll(": "); | 439 | try counting_stderr.writeAll(": "); |
| 440 | // This is the length of the part before the error message: | 440 | // This is the length of the part before the error message: |
| 441 | // e.g. "file.zig:4:5: error: " | 441 | // e.g. "file.zig:4:5: error: " |
| 442 | const prefix_len = @intCast(usize, counting_stderr.context.bytes_written); | 442 | const prefix_len = @intCast(usize, counting_stderr.context.bytes_written); |
| 443 | ttyconf.setColor(stderr, .Reset); | 443 | try ttyconf.setColor(stderr, .Reset); |
| 444 | ttyconf.setColor(stderr, .Bold); | 444 | try ttyconf.setColor(stderr, .Bold); |
| 445 | if (src.count == 1) { | 445 | if (src.count == 1) { |
| 446 | try src.writeMsg(stderr, prefix_len); | 446 | try src.writeMsg(stderr, prefix_len); |
| 447 | try stderr.writeByte('\n'); | 447 | try stderr.writeByte('\n'); |
| 448 | } else { | 448 | } else { |
| 449 | try src.writeMsg(stderr, prefix_len); | 449 | try src.writeMsg(stderr, prefix_len); |
| 450 | ttyconf.setColor(stderr, .Dim); | 450 | try ttyconf.setColor(stderr, .Dim); |
| 451 | try stderr.print(" ({d} times)\n", .{src.count}); | 451 | try stderr.print(" ({d} times)\n", .{src.count}); |
| 452 | } | 452 | } |
| 453 | ttyconf.setColor(stderr, .Reset); | 453 | try ttyconf.setColor(stderr, .Reset); |
| 454 | if (src.source_line) |line| { | 454 | if (src.source_line) |line| { |
| 455 | for (line) |b| switch (b) { | 455 | for (line) |b| switch (b) { |
| 456 | '\t' => try stderr.writeByte(' '), | 456 | '\t' => try stderr.writeByte(' '), |
| ... | @@ -462,19 +462,19 @@ pub const AllErrors = struct { | ... | @@ -462,19 +462,19 @@ pub const AllErrors = struct { |
| 462 | // -1 since span.main includes the caret | 462 | // -1 since span.main includes the caret |
| 463 | const after_caret = src.span.end - src.span.main -| 1; | 463 | const after_caret = src.span.end - src.span.main -| 1; |
| 464 | try stderr.writeByteNTimes(' ', src.column - before_caret); | 464 | try stderr.writeByteNTimes(' ', src.column - before_caret); |
| 465 | ttyconf.setColor(stderr, .Green); | 465 | try ttyconf.setColor(stderr, .Green); |
| 466 | try stderr.writeByteNTimes('~', before_caret); | 466 | try stderr.writeByteNTimes('~', before_caret); |
| 467 | try stderr.writeByte('^'); | 467 | try stderr.writeByte('^'); |
| 468 | try stderr.writeByteNTimes('~', after_caret); | 468 | try stderr.writeByteNTimes('~', after_caret); |
| 469 | try stderr.writeByte('\n'); | 469 | try stderr.writeByte('\n'); |
| 470 | ttyconf.setColor(stderr, .Reset); | 470 | try ttyconf.setColor(stderr, .Reset); |
| 471 | } | 471 | } |
| 472 | for (src.notes) |note| { | 472 | for (src.notes) |note| { |
| 473 | try note.renderToWriter(ttyconf, stderr, "note", .Cyan, indent); | 473 | try note.renderToWriter(ttyconf, stderr, "note", .Cyan, indent); |
| 474 | } | 474 | } |
| 475 | if (src.reference_trace.len != 0) { | 475 | if (src.reference_trace.len != 0) { |
| 476 | ttyconf.setColor(stderr, .Reset); | 476 | try ttyconf.setColor(stderr, .Reset); |
| 477 | ttyconf.setColor(stderr, .Dim); | 477 | try ttyconf.setColor(stderr, .Dim); |
| 478 | try stderr.print("referenced by:\n", .{}); | 478 | try stderr.print("referenced by:\n", .{}); |
| 479 | for (src.reference_trace) |reference| { | 479 | for (src.reference_trace) |reference| { |
| 480 | switch (reference) { | 480 | switch (reference) { |
| ... | @@ -498,23 +498,23 @@ pub const AllErrors = struct { | ... | @@ -498,23 +498,23 @@ pub const AllErrors = struct { |
| 498 | } | 498 | } |
| 499 | } | 499 | } |
| 500 | try stderr.writeByte('\n'); | 500 | try stderr.writeByte('\n'); |
| 501 | ttyconf.setColor(stderr, .Reset); | 501 | try ttyconf.setColor(stderr, .Reset); |
| 502 | } | 502 | } |
| 503 | }, | 503 | }, |
| 504 | .plain => |plain| { | 504 | .plain => |plain| { |
| 505 | ttyconf.setColor(stderr, color); | 505 | try ttyconf.setColor(stderr, color); |
| 506 | try stderr.writeByteNTimes(' ', indent); | 506 | try stderr.writeByteNTimes(' ', indent); |
| 507 | try stderr.writeAll(kind); | 507 | try stderr.writeAll(kind); |
| 508 | try stderr.writeAll(": "); | 508 | try stderr.writeAll(": "); |
| 509 | ttyconf.setColor(stderr, .Reset); | 509 | try ttyconf.setColor(stderr, .Reset); |
| 510 | if (plain.count == 1) { | 510 | if (plain.count == 1) { |
| 511 | try stderr.print("{s}\n", .{plain.msg}); | 511 | try stderr.print("{s}\n", .{plain.msg}); |
| 512 | } else { | 512 | } else { |
| 513 | try stderr.print("{s}", .{plain.msg}); | 513 | try stderr.print("{s}", .{plain.msg}); |
| 514 | ttyconf.setColor(stderr, .Dim); | 514 | try ttyconf.setColor(stderr, .Dim); |
| 515 | try stderr.print(" ({d} times)\n", .{plain.count}); | 515 | try stderr.print(" ({d} times)\n", .{plain.count}); |
| 516 | } | 516 | } |
| 517 | ttyconf.setColor(stderr, .Reset); | 517 | try ttyconf.setColor(stderr, .Reset); |
| 518 | for (plain.notes) |note| { | 518 | for (plain.notes) |note| { |
| 519 | try note.renderToWriter(ttyconf, stderr, "note", .Cyan, indent + 4); | 519 | try note.renderToWriter(ttyconf, stderr, "note", .Cyan, indent + 4); |
| 520 | } | 520 | } |