TUI editor and editor backend written in Zig
1const std = @import("std");
2
3const Formatter = @import("../Formatter.zig");
4
5const ZigFmt = @This();
6
7pub fn init() Formatter {
8 return .{
9 .vtable = &.{
10 .format = format,
11 },
12 };
13}
14
15pub fn format(f: *Formatter, gpa: std.mem.Allocator, input: []const u8) anyerror![]const u8 {
16 _ = f;
17 const log = std.log.scoped(.zig_fmt);
18
19 log.debug("formatting with `zig fmt`:\n{s}", .{input});
20
21 var child = std.process.Child.init(&.{ "zig", "fmt", "--stdin" }, gpa);
22 child.stdin_behavior = .Pipe;
23 child.stdout_behavior = .Pipe;
24 child.stderr_behavior = .Pipe;
25 errdefer _ = child.kill() catch void;
26
27 try child.spawn();
28
29 const stdin = child.stdin.?;
30
31 var buffer: [4096]u8 = undefined;
32 var w = stdin.writer(&buffer);
33 _ = try w.interface.writeAll(input);
34 try w.interface.flush();
35
36 stdin.close();
37 child.stdin = null;
38
39 var out: std.ArrayList(u8) = .empty;
40 var err: std.ArrayList(u8) = .empty;
41 defer out.deinit(gpa);
42 defer err.deinit(gpa);
43
44 // FIXME: maxInt(usize) is probably excessive here?
45 try child.collectOutput(gpa, &out, &err, std.math.maxInt(usize));
46
47 log.debug("stdout:\n{s}", .{out.items});
48 log.debug("stderr:\n{s}", .{err.items});
49
50 const result = try child.wait();
51
52 log.debug("result: {}", .{result});
53
54 if (result.Exited == 0) return out.toOwnedSlice(gpa);
55
56 return error.FailedToFormat;
57}