Zig 0.15: zig build test

This commit is contained in:
Mitchell Hashimoto
2025-10-01 13:10:40 -07:00
parent 3770f97608
commit cb295b84a0
66 changed files with 1264 additions and 1144 deletions

View File

@@ -3417,10 +3417,10 @@ pub fn loadFile(self: *Config, alloc: Allocator, path: []const u8) !void {
defer file.close();
std.log.info("reading configuration file path={s}", .{path});
var buf_reader = std.io.bufferedReader(file.reader());
const reader = buf_reader.reader();
const Iter = cli.args.LineIterator(@TypeOf(reader));
var iter: Iter = .{ .r = reader, .filepath = path };
var buf: [2048]u8 = undefined;
var file_reader = file.reader(&buf);
const reader = &file_reader.interface;
var iter: cli.args.LineIterator = .{ .r = reader, .filepath = path };
try self.loadIter(alloc, &iter);
try self.expandPaths(std.fs.path.dirname(path).?);
}
@@ -3457,8 +3457,10 @@ fn writeConfigTemplate(path: []const u8) !void {
}
const file = try std.fs.createFileAbsolute(path, .{});
defer file.close();
try std.fmt.format(
file.writer(),
var buf: [4096]u8 = undefined;
var file_writer = file.writer(&buf);
const writer = &file_writer.interface;
try writer.print(
@embedFile("./config-template"),
.{ .path = path },
);
@@ -3628,17 +3630,17 @@ pub fn loadCliArgs(self: *Config, alloc_gpa: Allocator) !void {
// Next, take all remaining args and use that to build up
// a command to execute.
var builder = std.ArrayList([:0]const u8).init(arena_alloc);
errdefer builder.deinit();
var builder: std.ArrayList([:0]const u8) = .empty;
errdefer builder.deinit(arena_alloc);
for (args) |arg_raw| {
const arg = std.mem.sliceTo(arg_raw, 0);
const copy = try arena_alloc.dupeZ(u8, arg);
try self._replay_steps.append(arena_alloc, .{ .arg = copy });
try builder.append(copy);
try builder.append(arena_alloc, copy);
}
self.@"_xdg-terminal-exec" = true;
self.@"initial-command" = .{ .direct = try builder.toOwnedSlice() };
self.@"initial-command" = .{ .direct = try builder.toOwnedSlice(arena_alloc) };
return;
}
}
@@ -3710,13 +3712,13 @@ pub fn loadRecursiveFiles(self: *Config, alloc_gpa: Allocator) !void {
// PRIOR to the "-e" in our replay steps, since everything
// after "-e" becomes an "initial-command". To do this, we
// dupe the values if we find it.
var replay_suffix = std.ArrayList(Replay.Step).init(alloc_gpa);
defer replay_suffix.deinit();
var replay_suffix: std.ArrayList(Replay.Step) = .empty;
defer replay_suffix.deinit(alloc_gpa);
for (self._replay_steps.items, 0..) |step, i| if (step == .@"-e") {
// We don't need to clone the steps because they should
// all be allocated in our arena and we're keeping our
// arena.
try replay_suffix.appendSlice(self._replay_steps.items[i..]);
try replay_suffix.appendSlice(alloc_gpa, self._replay_steps.items[i..]);
// Remove our old values. Again, don't need to free any
// memory here because its all part of our arena.
@@ -3744,10 +3746,11 @@ pub fn loadRecursiveFiles(self: *Config, alloc_gpa: Allocator) !void {
// We must only load a unique file once
if (try loaded.fetchPut(path, {}) != null) {
const diag: cli.Diagnostic = .{
.message = try std.fmt.allocPrintZ(
.message = try std.fmt.allocPrintSentinel(
arena_alloc,
"config-file {s}: cycle detected",
.{path},
0,
),
};
@@ -3759,10 +3762,11 @@ pub fn loadRecursiveFiles(self: *Config, alloc_gpa: Allocator) !void {
var file = std.fs.openFileAbsolute(path, .{}) catch |err| {
if (err != error.FileNotFound or !optional) {
const diag: cli.Diagnostic = .{
.message = try std.fmt.allocPrintZ(
.message = try std.fmt.allocPrintSentinel(
arena_alloc,
"error opening config-file {s}: {}",
.{ path, err },
0,
),
};
@@ -3778,10 +3782,11 @@ pub fn loadRecursiveFiles(self: *Config, alloc_gpa: Allocator) !void {
.file => {},
else => |kind| {
const diag: cli.Diagnostic = .{
.message = try std.fmt.allocPrintZ(
.message = try std.fmt.allocPrintSentinel(
arena_alloc,
"config-file {s}: not reading because file type is {s}",
.{ path, @tagName(kind) },
0,
),
};
@@ -3792,10 +3797,10 @@ pub fn loadRecursiveFiles(self: *Config, alloc_gpa: Allocator) !void {
}
log.info("loading config-file path={s}", .{path});
var buf_reader = std.io.bufferedReader(file.reader());
const reader = buf_reader.reader();
const Iter = cli.args.LineIterator(@TypeOf(reader));
var iter: Iter = .{ .r = reader, .filepath = path };
var buf: [2048]u8 = undefined;
var file_reader = file.reader(&buf);
const reader = &file_reader.interface;
var iter: cli.args.LineIterator = .{ .r = reader, .filepath = path };
try self.loadIter(alloc_gpa, &iter);
try self.expandPaths(std.fs.path.dirname(path).?);
}
@@ -3944,10 +3949,10 @@ fn loadTheme(self: *Config, theme: Theme) !void {
errdefer new_config.deinit();
// Load our theme
var buf_reader = std.io.bufferedReader(file.reader());
const reader = buf_reader.reader();
const Iter = cli.args.LineIterator(@TypeOf(reader));
var iter: Iter = .{ .r = reader, .filepath = path };
var buf: [2048]u8 = undefined;
var file_reader = file.reader(&buf);
const reader = &file_reader.interface;
var iter: cli.args.LineIterator = .{ .r = reader, .filepath = path };
try new_config.loadIter(alloc_gpa, &iter);
// Setup our replay to be conditional.
@@ -4190,7 +4195,7 @@ pub fn finalize(self: *Config) !void {
if (self.@"quit-after-last-window-closed-delay") |duration| {
if (duration.duration < 5 * std.time.ns_per_s) {
log.warn(
"quit-after-last-window-closed-delay is set to a very short value ({}), which might cause problems",
"quit-after-last-window-closed-delay is set to a very short value ({f}), which might cause problems",
.{duration},
);
}
@@ -4221,22 +4226,23 @@ pub fn parseManuallyHook(
// Build up the command. We don't clean this up because we take
// ownership in our allocator.
var command: std.ArrayList([:0]const u8) = .init(alloc);
errdefer command.deinit();
var command: std.ArrayList([:0]const u8) = .empty;
errdefer command.deinit(alloc);
while (iter.next()) |param| {
const copy = try alloc.dupeZ(u8, param);
try self._replay_steps.append(alloc, .{ .arg = copy });
try command.append(copy);
try command.append(alloc, copy);
}
if (command.items.len == 0) {
try self._diagnostics.append(alloc, .{
.location = try cli.Location.fromIter(iter, alloc),
.message = try std.fmt.allocPrintZ(
.message = try std.fmt.allocPrintSentinel(
alloc,
"missing command after {s}",
.{arg},
0,
),
});
@@ -4371,10 +4377,11 @@ pub fn addDiagnosticFmt(
) Allocator.Error!void {
const alloc = self._arena.?.allocator();
try self._diagnostics.append(alloc, .{
.message = try std.fmt.allocPrintZ(
.message = try std.fmt.allocPrintSentinel(
alloc,
fmt,
args,
0,
),
});
}
@@ -4892,7 +4899,7 @@ pub const Color = struct {
}
/// Used by Formatter
pub fn formatEntry(self: Color, formatter: anytype) !void {
pub fn formatEntry(self: Color, formatter: formatterpkg.EntryFormatter) !void {
var buf: [128]u8 = undefined;
try formatter.formatEntry(
[]const u8,
@@ -4959,12 +4966,12 @@ pub const Color = struct {
test "formatConfig" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var color: Color = .{ .r = 10, .g = 11, .b = 12 };
try color.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = #0a0b0c\n", buf.items);
try color.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try std.testing.expectEqualSlices(u8, "a = #0a0b0c\n", buf.written());
}
test "parseCLI with whitespace" {
@@ -4995,7 +5002,7 @@ pub const TerminalColor = union(enum) {
}
/// Used by Formatter
pub fn formatEntry(self: TerminalColor, formatter: anytype) !void {
pub fn formatEntry(self: TerminalColor, formatter: formatterpkg.EntryFormatter) !void {
switch (self) {
.color => try self.color.formatEntry(formatter),
@@ -5030,12 +5037,12 @@ pub const TerminalColor = union(enum) {
test "formatConfig" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var sc: TerminalColor = .@"cell-foreground";
try sc.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try testing.expectEqualSlices(u8, "a = cell-foreground\n", buf.items);
try sc.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try testing.expectEqualSlices(u8, "a = cell-foreground\n", buf.written());
}
};
@@ -5051,7 +5058,7 @@ pub const BoldColor = union(enum) {
}
/// Used by Formatter
pub fn formatEntry(self: BoldColor, formatter: anytype) !void {
pub fn formatEntry(self: BoldColor, formatter: formatterpkg.EntryFormatter) !void {
switch (self) {
.color => try self.color.formatEntry(formatter),
.bright => try formatter.formatEntry(
@@ -5082,12 +5089,12 @@ pub const BoldColor = union(enum) {
test "formatConfig" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var sc: BoldColor = .bright;
try sc.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try testing.expectEqualSlices(u8, "a = bright\n", buf.items);
try sc.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try testing.expectEqualSlices(u8, "a = bright\n", buf.written());
}
};
@@ -5174,8 +5181,7 @@ pub const ColorList = struct {
// Build up the value of our config. Our buffer size should be
// sized to contain all possible maximum values.
var buf: [1024]u8 = undefined;
var fbs = std.io.fixedBufferStream(&buf);
var writer = fbs.writer();
var writer: std.Io.Writer = .fixed(&buf);
for (self.colors.items, 0..) |color, i| {
var color_buf: [128]u8 = undefined;
const color_str = try color.formatBuf(&color_buf);
@@ -5185,7 +5191,7 @@ pub const ColorList = struct {
try formatter.formatEntry(
[]const u8,
fbs.getWritten(),
writer.buffered(),
);
}
@@ -5214,7 +5220,7 @@ pub const ColorList = struct {
test "format" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var arena = ArenaAllocator.init(testing.allocator);
@@ -5223,8 +5229,8 @@ pub const ColorList = struct {
var p: Self = .{};
try p.parseCLI(alloc, "black,white");
try p.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = #000000,#ffffff\n", buf.items);
try p.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try std.testing.expectEqualSlices(u8, "a = #000000,#ffffff\n", buf.written());
}
};
@@ -5285,7 +5291,7 @@ pub const Palette = struct {
}
/// Used by Formatter
pub fn formatEntry(self: Self, formatter: anytype) !void {
pub fn formatEntry(self: Self, formatter: formatterpkg.EntryFormatter) !void {
var buf: [128]u8 = undefined;
for (0.., self.value) |k, v| {
try formatter.formatEntry(
@@ -5340,12 +5346,12 @@ pub const Palette = struct {
test "formatConfig" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var list: Self = .{};
try list.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = 0=#1d1f21\n", buf.items[0..14]);
try list.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try std.testing.expectEqualSlices(u8, "a = 0=#1d1f21\n", buf.written()[0..14]);
}
test "parseCLI with whitespace" {
@@ -5439,7 +5445,7 @@ pub const RepeatableString = struct {
}
/// Used by Formatter
pub fn formatEntry(self: Self, formatter: anytype) !void {
pub fn formatEntry(self: Self, formatter: formatterpkg.EntryFormatter) !void {
// If no items, we want to render an empty field.
if (self.list.items.len == 0) {
try formatter.formatEntry(void, {});
@@ -5486,17 +5492,17 @@ pub const RepeatableString = struct {
test "formatConfig empty" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var list: Self = .{};
try list.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = \n", buf.items);
try list.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try std.testing.expectEqualSlices(u8, "a = \n", buf.written());
}
test "formatConfig single item" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var arena = ArenaAllocator.init(testing.allocator);
@@ -5505,13 +5511,13 @@ pub const RepeatableString = struct {
var list: Self = .{};
try list.parseCLI(alloc, "A");
try list.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = A\n", buf.items);
try list.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try std.testing.expectEqualSlices(u8, "a = A\n", buf.written());
}
test "formatConfig multiple items" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var arena = ArenaAllocator.init(testing.allocator);
@@ -5521,8 +5527,8 @@ pub const RepeatableString = struct {
var list: Self = .{};
try list.parseCLI(alloc, "A");
try list.parseCLI(alloc, "B");
try list.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = A\na = B\n", buf.items);
try list.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try std.testing.expectEqualSlices(u8, "a = A\na = B\n", buf.written());
}
};
@@ -5638,7 +5644,7 @@ pub const RepeatableFontVariation = struct {
test "formatConfig single" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var arena = ArenaAllocator.init(testing.allocator);
@@ -5647,8 +5653,8 @@ pub const RepeatableFontVariation = struct {
var list: Self = .{};
try list.parseCLI(alloc, "wght = 200");
try list.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = wght=200\n", buf.items);
try list.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try std.testing.expectEqualSlices(u8, "a = wght=200\n", buf.written());
}
};
@@ -6449,7 +6455,7 @@ pub const Keybinds = struct {
}
/// Like formatEntry but has an option to include docs.
pub fn formatEntryDocs(self: Keybinds, formatter: anytype, docs: bool) !void {
pub fn formatEntryDocs(self: Keybinds, formatter: formatterpkg.EntryFormatter, docs: bool) !void {
if (self.set.bindings.size == 0) {
try formatter.formatEntry(void, {});
return;
@@ -6478,14 +6484,14 @@ pub const Keybinds = struct {
}
}
var buffer_stream = std.io.fixedBufferStream(&buf);
std.fmt.format(buffer_stream.writer(), "{}", .{k}) catch return error.OutOfMemory;
try v.formatEntries(&buffer_stream, formatter);
var writer: std.Io.Writer = .fixed(&buf);
writer.print("{f}", .{k}) catch return error.OutOfMemory;
try v.formatEntries(&writer, formatter);
}
}
/// Used by Formatter
pub fn formatEntry(self: Keybinds, formatter: anytype) !void {
pub fn formatEntry(self: Keybinds, formatter: formatterpkg.EntryFormatter) !void {
try self.formatEntryDocs(formatter, false);
}
@@ -6502,7 +6508,7 @@ pub const Keybinds = struct {
test "formatConfig single" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var arena = ArenaAllocator.init(testing.allocator);
@@ -6511,14 +6517,14 @@ pub const Keybinds = struct {
var list: Keybinds = .{};
try list.parseCLI(alloc, "shift+a=csi:hello");
try list.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = shift+a=csi:hello\n", buf.items);
try list.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try std.testing.expectEqualSlices(u8, "a = shift+a=csi:hello\n", buf.written());
}
// Regression test for https://github.com/ghostty-org/ghostty/issues/2734
test "formatConfig multiple items" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var arena = ArenaAllocator.init(testing.allocator);
@@ -6528,7 +6534,7 @@ pub const Keybinds = struct {
var list: Keybinds = .{};
try list.parseCLI(alloc, "ctrl+z>1=goto_tab:1");
try list.parseCLI(alloc, "ctrl+z>2=goto_tab:2");
try list.formatEntry(formatterpkg.entryFormatter("keybind", buf.writer()));
try list.formatEntry(formatterpkg.entryFormatter("keybind", &buf.writer));
// Note they turn into translated keys because they match
// their ASCII mapping.
@@ -6537,12 +6543,12 @@ pub const Keybinds = struct {
\\keybind = ctrl+z>1=goto_tab:1
\\
;
try std.testing.expectEqualStrings(want, buf.items);
try std.testing.expectEqualStrings(want, buf.written());
}
test "formatConfig multiple items nested" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var arena = ArenaAllocator.init(testing.allocator);
@@ -6554,7 +6560,7 @@ pub const Keybinds = struct {
try list.parseCLI(alloc, "ctrl+a>ctrl+b>w=close_window");
try list.parseCLI(alloc, "ctrl+a>ctrl+c>t=new_tab");
try list.parseCLI(alloc, "ctrl+b>ctrl+d>a=previous_tab");
try list.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try list.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
// NB: This does not currently retain the order of the keybinds.
const want =
@@ -6564,7 +6570,7 @@ pub const Keybinds = struct {
\\a = ctrl+b>ctrl+d>a=previous_tab
\\
;
try std.testing.expectEqualStrings(want, buf.items);
try std.testing.expectEqualStrings(want, buf.written());
}
};
@@ -6790,7 +6796,7 @@ pub const RepeatableCodepointMap = struct {
test "formatConfig single" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var arena = ArenaAllocator.init(testing.allocator);
@@ -6799,13 +6805,13 @@ pub const RepeatableCodepointMap = struct {
var list: Self = .{};
try list.parseCLI(alloc, "U+ABCD=Comic Sans");
try list.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = U+ABCD=Comic Sans\n", buf.items);
try list.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try std.testing.expectEqualSlices(u8, "a = U+ABCD=Comic Sans\n", buf.written());
}
test "formatConfig range" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var arena = ArenaAllocator.init(testing.allocator);
@@ -6814,13 +6820,13 @@ pub const RepeatableCodepointMap = struct {
var list: Self = .{};
try list.parseCLI(alloc, "U+0001 - U+0005=Verdana");
try list.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = U+0001-U+0005=Verdana\n", buf.items);
try list.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try std.testing.expectEqualSlices(u8, "a = U+0001-U+0005=Verdana\n", buf.written());
}
test "formatConfig multiple" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var arena = ArenaAllocator.init(testing.allocator);
@@ -6829,12 +6835,12 @@ pub const RepeatableCodepointMap = struct {
var list: Self = .{};
try list.parseCLI(alloc, "U+0006-U+0009, U+ABCD=Courier");
try list.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try list.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try std.testing.expectEqualSlices(u8,
\\a = U+0006-U+0009=Courier
\\a = U+ABCD=Courier
\\
, buf.items);
, buf.written());
}
};
@@ -6886,7 +6892,7 @@ pub const FontStyle = union(enum) {
}
/// Used by Formatter
pub fn formatEntry(self: Self, formatter: anytype) !void {
pub fn formatEntry(self: Self, formatter: formatterpkg.EntryFormatter) !void {
switch (self) {
.default, .false => try formatter.formatEntry(
[]const u8,
@@ -6918,7 +6924,7 @@ pub const FontStyle = union(enum) {
test "formatConfig default" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var arena = ArenaAllocator.init(testing.allocator);
@@ -6927,13 +6933,13 @@ pub const FontStyle = union(enum) {
var p: Self = .{ .default = {} };
try p.parseCLI(alloc, "default");
try p.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = default\n", buf.items);
try p.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try std.testing.expectEqualSlices(u8, "a = default\n", buf.written());
}
test "formatConfig false" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var arena = ArenaAllocator.init(testing.allocator);
@@ -6942,13 +6948,13 @@ pub const FontStyle = union(enum) {
var p: Self = .{ .default = {} };
try p.parseCLI(alloc, "false");
try p.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = false\n", buf.items);
try p.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try std.testing.expectEqualSlices(u8, "a = false\n", buf.written());
}
test "formatConfig named" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var arena = ArenaAllocator.init(testing.allocator);
@@ -6957,8 +6963,8 @@ pub const FontStyle = union(enum) {
var p: Self = .{ .default = {} };
try p.parseCLI(alloc, "bold");
try p.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = bold\n", buf.items);
try p.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try std.testing.expectEqualSlices(u8, "a = bold\n", buf.written());
}
};
@@ -7018,7 +7024,7 @@ pub const RepeatableLink = struct {
}
/// Used by Formatter
pub fn formatEntry(self: Self, formatter: anytype) !void {
pub fn formatEntry(self: Self, formatter: formatterpkg.EntryFormatter) !void {
// This currently can't be set so we don't format anything.
_ = self;
_ = formatter;
@@ -7128,7 +7134,10 @@ pub const RepeatableCommand = struct {
}
/// Used by Formatter
pub fn formatEntry(self: RepeatableCommand, formatter: anytype) !void {
pub fn formatEntry(
self: RepeatableCommand,
formatter: formatterpkg.EntryFormatter,
) !void {
if (self.value.items.len == 0) {
try formatter.formatEntry(void, {});
return;
@@ -7136,22 +7145,23 @@ pub const RepeatableCommand = struct {
for (self.value.items) |item| {
var buf: [4096]u8 = undefined;
var fbs = std.io.fixedBufferStream(&buf);
var writer = fbs.writer();
var writer: std.Io.Writer = .fixed(&buf);
writer.writeAll("title:\"") catch return error.OutOfMemory;
std.zig.stringEscape(item.title, "", .{}, writer) catch return error.OutOfMemory;
writer.writeAll("\"") catch return error.OutOfMemory;
writer.print(
"title:\"{f}\"",
.{std.zig.fmtString(item.title)},
) catch return error.OutOfMemory;
if (item.description.len > 0) {
writer.writeAll(",description:\"") catch return error.OutOfMemory;
std.zig.stringEscape(item.description, "", .{}, writer) catch return error.OutOfMemory;
writer.writeAll("\"") catch return error.OutOfMemory;
writer.print(
",description:\"{f}\"",
.{std.zig.fmtString(item.description)},
) catch return error.OutOfMemory;
}
writer.print(",action:\"{}\"", .{item.action}) catch return error.OutOfMemory;
writer.print(",action:\"{f}\"", .{item.action}) catch return error.OutOfMemory;
try formatter.formatEntry([]const u8, fbs.getWritten());
try formatter.formatEntry([]const u8, writer.buffered());
}
}
@@ -7197,17 +7207,17 @@ pub const RepeatableCommand = struct {
test "RepeatableCommand formatConfig empty" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var list: RepeatableCommand = .{};
try list.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = \n", buf.items);
try list.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try std.testing.expectEqualSlices(u8, "a = \n", buf.written());
}
test "RepeatableCommand formatConfig single item" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var arena = ArenaAllocator.init(testing.allocator);
@@ -7216,13 +7226,13 @@ pub const RepeatableCommand = struct {
var list: RepeatableCommand = .{};
try list.parseCLI(alloc, "title:Bobr, action:text:Bober");
try list.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = title:\"Bobr\",action:\"text:Bober\"\n", buf.items);
try list.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try std.testing.expectEqualSlices(u8, "a = title:\"Bobr\",action:\"text:Bober\"\n", buf.written());
}
test "RepeatableCommand formatConfig multiple items" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var arena = ArenaAllocator.init(testing.allocator);
@@ -7232,14 +7242,12 @@ pub const RepeatableCommand = struct {
var list: RepeatableCommand = .{};
try list.parseCLI(alloc, "title:Bobr, action:text:kurwa");
try list.parseCLI(alloc, "title:Ja, description: pierdole, action:text:jakie bydle");
try list.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualSlices(u8, "a = title:\"Bobr\",action:\"text:kurwa\"\na = title:\"Ja\",description:\"pierdole\",action:\"text:jakie bydle\"\n", buf.items);
try list.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try std.testing.expectEqualSlices(u8, "a = title:\"Bobr\",action:\"text:kurwa\"\na = title:\"Ja\",description:\"pierdole\",action:\"text:jakie bydle\"\n", buf.written());
}
test "RepeatableCommand parseCLI commas" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
defer buf.deinit();
var arena = ArenaAllocator.init(testing.allocator);
defer arena.deinit();
@@ -7455,14 +7463,14 @@ pub const MouseScrollMultiplier = struct {
}
/// Used by Formatter
pub fn formatEntry(self: Self, formatter: anytype) !void {
var buf: [32]u8 = undefined;
const formatted = std.fmt.bufPrint(
&buf,
pub fn formatEntry(self: Self, formatter: formatterpkg.EntryFormatter) !void {
var buf: [4096]u8 = undefined;
var writer: std.Io.Writer = .fixed(&buf);
writer.print(
"precision:{d},discrete:{d}",
.{ self.precision, self.discrete },
) catch return error.OutOfMemory;
try formatter.formatEntry([]const u8, formatted);
try formatter.formatEntry([]const u8, writer.buffered());
}
test "parse" {
@@ -7505,12 +7513,12 @@ pub const MouseScrollMultiplier = struct {
test "format entry MouseScrollMultiplier" {
const testing = std.testing;
var buf = std.ArrayList(u8).init(testing.allocator);
var buf: std.Io.Writer.Allocating = .init(testing.allocator);
defer buf.deinit();
var args: Self = .{ .precision = 1.5, .discrete = 2.5 };
try args.formatEntry(formatterpkg.entryFormatter("mouse-scroll-multiplier", buf.writer()));
try testing.expectEqualSlices(u8, "mouse-scroll-multiplier = precision:1.5,discrete:2.5\n", buf.items);
try args.formatEntry(formatterpkg.entryFormatter("mouse-scroll-multiplier", &buf.writer));
try testing.expectEqualSlices(u8, "mouse-scroll-multiplier = precision:1.5,discrete:2.5\n", buf.written());
}
};
@@ -7627,7 +7635,7 @@ pub const QuickTerminalSize = struct {
return error.MissingUnit;
}
fn format(self: Size, writer: anytype) !void {
fn format(self: Size, writer: *std.Io.Writer) !void {
switch (self) {
.percentage => |v| try writer.print("{d}%", .{v}),
.pixels => |v| try writer.print("{}px", .{v}),
@@ -7745,20 +7753,19 @@ pub const QuickTerminalSize = struct {
};
}
pub fn formatEntry(self: QuickTerminalSize, formatter: anytype) !void {
pub fn formatEntry(self: QuickTerminalSize, formatter: formatterpkg.EntryFormatter) !void {
const primary = self.primary orelse return;
var buf: [4096]u8 = undefined;
var fbs = std.io.fixedBufferStream(&buf);
const writer = fbs.writer();
var writer: std.Io.Writer = .fixed(&buf);
primary.format(writer) catch return error.OutOfMemory;
primary.format(&writer) catch return error.OutOfMemory;
if (self.secondary) |secondary| {
writer.writeByte(',') catch return error.OutOfMemory;
secondary.format(writer) catch return error.OutOfMemory;
secondary.format(&writer) catch return error.OutOfMemory;
}
try formatter.formatEntry([]const u8, fbs.getWritten());
try formatter.formatEntry([]const u8, writer.buffered());
}
test "parse QuickTerminalSize" {
@@ -8318,15 +8325,17 @@ pub const Duration = struct {
return if (value) |v| .{ .duration = v } else error.ValueRequired;
}
pub fn formatEntry(self: Duration, formatter: anytype) !void {
pub fn formatEntry(self: Duration, formatter: formatterpkg.EntryFormatter) !void {
var buf: [64]u8 = undefined;
var fbs = std.io.fixedBufferStream(&buf);
const writer = fbs.writer();
try self.format("", .{}, writer);
try formatter.formatEntry([]const u8, fbs.getWritten());
var writer: std.Io.Writer = .fixed(&buf);
try self.format(&writer);
try formatter.formatEntry([]const u8, writer.buffered());
}
pub fn format(self: Duration, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void {
pub fn format(
self: Duration,
writer: *std.Io.Writer,
) !void {
var value = self.duration;
var i: usize = 0;
for (units) |unit| {
@@ -8393,7 +8402,7 @@ pub const WindowPadding = struct {
}
}
pub fn formatEntry(self: Self, formatter: anytype) !void {
pub fn formatEntry(self: Self, formatter: formatterpkg.EntryFormatter) !void {
var buf: [128]u8 = undefined;
if (self.top_left == self.bottom_right) {
try formatter.formatEntry(
@@ -8555,7 +8564,7 @@ test "test format" {
inline for (Duration.units) |unit| {
const d: Duration = .{ .duration = unit.factor };
var actual_buf: [16]u8 = undefined;
const actual = try std.fmt.bufPrint(&actual_buf, "{}", .{d});
const actual = try std.fmt.bufPrint(&actual_buf, "{f}", .{d});
var expected_buf: [16]u8 = undefined;
const expected = if (!std.mem.eql(u8, unit.name, "us"))
try std.fmt.bufPrint(&expected_buf, "1{s}", .{unit.name})
@@ -8566,12 +8575,12 @@ test "test format" {
}
test "test entryFormatter" {
var buf = std.ArrayList(u8).init(std.testing.allocator);
var buf: std.Io.Writer.Allocating = .init(std.testing.allocator);
defer buf.deinit();
var p: Duration = .{ .duration = std.math.maxInt(u64) };
try p.formatEntry(formatterpkg.entryFormatter("a", buf.writer()));
try std.testing.expectEqualStrings("a = 584y 49w 23h 34m 33s 709ms 551µs 615ns\n", buf.items);
try p.formatEntry(formatterpkg.entryFormatter("a", &buf.writer));
try std.testing.expectEqualStrings("a = 584y 49w 23h 34m 33s 709ms 551µs 615ns\n", buf.written());
}
const TestIterator = struct {
@@ -8681,15 +8690,20 @@ test "clone can then change conditional state" {
// Setup our test theme
var td = try internal_os.TempDir.init();
defer td.deinit();
var buf: [4096]u8 = undefined;
{
var file = try td.dir.createFile("theme_light", .{});
defer file.close();
try file.writer().writeAll(@embedFile("testdata/theme_light"));
var writer = file.writer(&buf);
try writer.interface.writeAll(@embedFile("testdata/theme_light"));
try writer.end();
}
{
var file = try td.dir.createFile("theme_dark", .{});
defer file.close();
try file.writer().writeAll(@embedFile("testdata/theme_dark"));
var writer = file.writer(&buf);
try writer.interface.writeAll(@embedFile("testdata/theme_dark"));
try writer.end();
}
var light_buf: [std.fs.max_path_bytes]u8 = undefined;
const light = try td.dir.realpath("theme_light", &light_buf);
@@ -8815,10 +8829,13 @@ test "theme loading" {
// Setup our test theme
var td = try internal_os.TempDir.init();
defer td.deinit();
var buf: [4096]u8 = undefined;
{
var file = try td.dir.createFile("theme", .{});
defer file.close();
try file.writer().writeAll(@embedFile("testdata/theme_simple"));
var writer = file.writer(&buf);
try writer.interface.writeAll(@embedFile("testdata/theme_simple"));
try writer.end();
}
var path_buf: [std.fs.max_path_bytes]u8 = undefined;
const path = try td.dir.realpath("theme", &path_buf);
@@ -8851,10 +8868,13 @@ test "theme loading preserves conditional state" {
// Setup our test theme
var td = try internal_os.TempDir.init();
defer td.deinit();
var buf: [4096]u8 = undefined;
{
var file = try td.dir.createFile("theme", .{});
defer file.close();
try file.writer().writeAll(@embedFile("testdata/theme_simple"));
var writer = file.writer(&buf);
try writer.interface.writeAll(@embedFile("testdata/theme_simple"));
try writer.end();
}
var path_buf: [std.fs.max_path_bytes]u8 = undefined;
const path = try td.dir.realpath("theme", &path_buf);
@@ -8881,10 +8901,13 @@ test "theme priority is lower than config" {
// Setup our test theme
var td = try internal_os.TempDir.init();
defer td.deinit();
var buf: [4096]u8 = undefined;
{
var file = try td.dir.createFile("theme", .{});
defer file.close();
try file.writer().writeAll(@embedFile("testdata/theme_simple"));
var writer = file.writer(&buf);
try writer.interface.writeAll(@embedFile("testdata/theme_simple"));
try writer.end();
}
var path_buf: [std.fs.max_path_bytes]u8 = undefined;
const path = try td.dir.realpath("theme", &path_buf);
@@ -8915,15 +8938,20 @@ test "theme loading correct light/dark" {
// Setup our test theme
var td = try internal_os.TempDir.init();
defer td.deinit();
var buf: [4096]u8 = undefined;
{
var file = try td.dir.createFile("theme_light", .{});
defer file.close();
try file.writer().writeAll(@embedFile("testdata/theme_light"));
var writer = file.writer(&buf);
try writer.interface.writeAll(@embedFile("testdata/theme_light"));
try writer.end();
}
{
var file = try td.dir.createFile("theme_dark", .{});
defer file.close();
try file.writer().writeAll(@embedFile("testdata/theme_dark"));
var writer = file.writer(&buf);
try writer.interface.writeAll(@embedFile("testdata/theme_dark"));
try writer.end();
}
var light_buf: [std.fs.max_path_bytes]u8 = undefined;
const light = try td.dir.realpath("theme_light", &light_buf);