╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ bsp.zig ──────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
145 { 146 var steps: std.ArrayList(Configuration.Step.Index) = .empty; 147 defer steps.deinit(gpa); 148 149 const watch = std.mem.startsWith(u8, command, "watch"); 150 151 if (std.mem.cutPrefix(u8, command, "build ") orelse 152 std.mem.cutPrefix(u8, command, "watch ")) |command_args| 153 { 154 var it = std.mem.tokenizeScalar(u8, command_args, ' '); 155 while (it.next()) |arg| { 156 const step: Configuration.Step.Index = 157 if (std.fmt.parseInt(u32, arg, 10)) |i| 158 @fromBackingInt(i) 159 else |_| 160 top_level_steps.get(arg) orelse std.debug.panic("unexpected step name or index", .{}); 161 try steps.append(gpa, step); 162 } 163 } 164 165 if (steps.items.len < 1) { 166 try steps.append(gpa, c.default_step); 167 } 168 169 try client.serveBuildSteps(steps.items, .{ .watch = watch }); 170 171 while (true) { 172 const header: Server.Message.Header = client.receiveMessageWithMultiReader(&multi_reader, .none) catch |err| switch (err) { 173 error.Canceled, error.ConcurrencyUnavailable => |e| return e, 174 error.Timeout => unreachable, 175 else => |e| { 176 log.err("failed to receive message: {t}", .{err}); 177 break :blk e; 178 }, 179 }; 180 const body = client_stdout.take(header.bytes_len) catch unreachable; 181 log.debug("received {f} ({d} bytes)", .{ fmtEnum(header.tag), body.len }); 182 183 switch (header.tag) { 184 .bsp_build_started => {}, 185 .bsp_build_completed => if (!watch) break, 186 .bsp_step_started => {}, 187 .bsp_step_completed => {}, 188 .bsp_configuration => @panic("TODO"), 189 else => std.debug.panic("received unexpected message: {f}", .{fmtEnum(header.tag)}), 190 } 191 } 192 continue; 193 } else if (std.mem.eql(u8, command, "exit")) { 194 try client.serveBodylessMessage(.exit); 195 break; 196 } else { 197 log.err("unknown command: {q}", .{command}); 198 continue; 199 } 200 } 201 }; 202 203 try multi_reader.fillRemaining(.none); 204 205 if (client_stderr.bufferedLen() > 0) { 206 log.err("stderr:\n{s}\n", .{client_stderr.buffered()}); 207 } 208 209 try err; 210 211 const term = try child_process.wait(io); 212 213 if (!term.success()) { 214 log.err("maker {f}", .{term}); 215 } 216 } 217 218 const FormatEnum = union(enum) { 219 named: []const u8, 220 unnamed: usize, 221 222 pub fn format( 223 e: FormatEnum, 224 writer: *std.Io.Writer, 225 ) std.Io.Writer.Error!void { 226 switch (e) { 227 .named => |name| { 228 try writer.writeByte('.'); 229 try writer.writeAll(name); 230 }, 231 .unnamed => |number| try writer.print("0x{x}", .{number}), 232 } 233 } 234 }; 235 236 fn fmtEnum(e: anytype) FormatEnum { 237 if (std.enums.tagName(@TypeOf(e), e)) |name| { 238 return .{ .named = name }; 239 } else { 240 return .{ .unnamed = @backingInt(e) }; 241 } 242 } 243