Просмотр исходного кода

Port over most remaining commands

What is still missing is the generic runner.
Luna Stadler лет назад: 4
Родитель
Сommit
660bc5d4f6
1 измененных файлов с 42 добавлено и 48 удалено
  1. 42 48
      zig/sdl/hello_sdl.zig

+ 42 - 48
zig/sdl/hello_sdl.zig

16
});
16
});
17
const std = @import("std");
17
const std = @import("std");
18
18
19
// TODO: restore commands
20
// TODO: instant output (for some commands like `py ...`, `go ...`, qcalc)
21
22
// commands wishlist:
19
// commands wishlist:
23
// - search (e.g. default current dir + /usr/include)
20
// - search (e.g. default current dir + /usr/include)
24
// - launch with logs (default launcher, use systemd-run --user --unit=name name?)
21
// - launch with logs (default launcher, use systemd-run --user --unit=name name?)
38
    stderr_buf: std.ArrayList(u8),
35
    stderr_buf: std.ArrayList(u8),
39
36
40
    dead_fds: usize = 0,
37
    dead_fds: usize = 0,
41
    max_output_bytes: usize = 50 * 1024,
38
    max_output_bytes: usize,
42
39
43
    cleanup_done: bool = false,
40
    cleanup_done: bool = false,
44
41
112
            const nread = try std.os.read(poll_fds[0].fd, buf);
109
            const nread = try std.os.read(poll_fds[0].fd, buf);
113
            self.stdout_buf.items.len += nread;
110
            self.stdout_buf.items.len += nread;
114
111
112
            std.debug.print("read {d} bytes ({d} total, {d} max)\n", .{ nread, self.stdout_buf.items.len, self.max_output_bytes });
113
115
            // Remove the fd when the EOF condition is met.
114
            // Remove the fd when the EOF condition is met.
116
            remove_stdout = nread == 0;
115
            remove_stdout = nread == 0;
117
        } else {
116
        } else {
152
};
151
};
153
152
154
const RegexRunner = struct {
153
const RegexRunner = struct {
154
    name: []const u8,
155
    run_always: bool,
155
    run_always: bool,
156
    process: ?ProcessWithOutput = null,
156
    process: ?ProcessWithOutput = null,
157
157
201
                    return err;
201
                    return err;
202
                },
202
                },
203
            };
203
            };
204
            //std.debug.print("{d} ({d})\n", .{process.stdout_buf.items.len, process.stderr_buf.items.len});
204
            std.debug.print("{d} ({d})\n", .{ process.stdout_buf.items.len, process.stderr_buf.items.len });
205
            if (process.stdout_buf.items.len > 0) {
205
            if (process.stdout_buf.items.len > 0) {
206
                return process.stdout();
206
                return process.stdout();
207
            } else if (process.stderr_buf.items.len > 0) {
207
            } else if (process.stderr_buf.items.len > 0) {
223
223
224
const GoDocRunner = struct {
224
const GoDocRunner = struct {
225
    fn init() RegexRunner {
225
    fn init() RegexRunner {
226
        return RegexRunner{ .run_always = true, .toArgv = toArgv, .isActive = isActive };
226
        return RegexRunner{ .name = "go doc", .run_always = true, .toArgv = toArgv, .isActive = isActive };
227
    }
227
    }
228
228
229
    fn isActive(cmd: []const u8) bool {
229
    fn isActive(cmd: []const u8) bool {
239
239
240
const PythonHelpRunner = struct {
240
const PythonHelpRunner = struct {
241
    fn init() RegexRunner {
241
    fn init() RegexRunner {
242
        return RegexRunner{ .run_always = true, .toArgv = toArgv, .isActive = isActive };
242
        return RegexRunner{ .name = "python help", .run_always = true, .toArgv = toArgv, .isActive = isActive };
243
    }
243
    }
244
244
245
    fn isActive(cmd: []const u8) bool {
245
    fn isActive(cmd: []const u8) bool {
254
254
255
const PythonRunner = struct {
255
const PythonRunner = struct {
256
    fn init() RegexRunner {
256
    fn init() RegexRunner {
257
        return RegexRunner{ .run_always = true, .toArgv = toArgv, .isActive = isActive };
257
        return RegexRunner{ .name = "python run", .run_always = true, .toArgv = toArgv, .isActive = isActive };
258
    }
258
    }
259
259
260
    fn isActive(cmd: []const u8) bool {
260
    fn isActive(cmd: []const u8) bool {
267
    }
267
    }
268
};
268
};
269
269
270
const HelpRunner = struct {
271
    fn init() RegexRunner {
272
        return RegexRunner{ .name = "--help", .run_always = true, .toArgv = toArgv, .isActive = isActive };
273
    }
274
275
    fn isActive(cmd: []const u8) bool {
276
        return std.mem.endsWith(u8, cmd, " --help");
277
    }
278
279
    fn toArgv(cmd: []const u8) []const []const u8 {
280
        _ = std.fmt.bufPrint(&cmd_buf, "{s}", .{cmd[0 .. cmd.len - " --help".len]}) catch "???";
281
        return &[_][]const u8{ &cmd_buf, "--help" };
282
    }
283
};
284
285
const ManPageRunner = struct {
286
    fn init() RegexRunner {
287
        return RegexRunner{ .name = "man page", .run_always = true, .toArgv = toArgv, .isActive = isActive };
288
    }
289
290
    fn isActive(cmd: []const u8) bool {
291
        return cmd.len > "man ".len + 2 and std.mem.startsWith(u8, cmd, "man ");
292
    }
293
294
    fn toArgv(cmd: []const u8) []const []const u8 {
295
        _ = std.fmt.bufPrint(&cmd_buf, "{s}", .{cmd["man ".len..]}) catch "???";
296
        return &[_][]const u8{ "man", &cmd_buf };
297
    }
298
};
299
270
const SearchRunner = struct {
300
const SearchRunner = struct {
271
    fn init() RegexRunner {
301
    fn init() RegexRunner {
272
        return RegexRunner{ .run_always = true, .toArgv = toArgv, .isActive = isActive };
302
        return RegexRunner{ .name = "search", .run_always = true, .toArgv = toArgv, .isActive = isActive };
273
    }
303
    }
274
304
275
    fn isActive(cmd: []const u8) bool {
305
    fn isActive(cmd: []const u8) bool {
284
314
285
const QalcRunner = struct {
315
const QalcRunner = struct {
286
    fn init() RegexRunner {
316
    fn init() RegexRunner {
287
        return RegexRunner{ .run_always = true, .toArgv = toArgv, .isActive = isActive };
317
        return RegexRunner{ .name = "qalc", .run_always = true, .toArgv = toArgv, .isActive = isActive };
288
    }
318
    }
289
319
290
    fn isActive(cmd: []const u8) bool {
320
    fn isActive(cmd: []const u8) bool {
366
        GoDocRunner.init(),
396
        GoDocRunner.init(),
367
        PythonHelpRunner.init(),
397
        PythonHelpRunner.init(),
368
        PythonRunner.init(),
398
        PythonRunner.init(),
399
        HelpRunner.init(),
400
        ManPageRunner.init(),
369
        SearchRunner.init(),
401
        SearchRunner.init(),
370
        QalcRunner.init(),
402
        QalcRunner.init(),
371
    };
403
    };
559
    }
591
    }
560
}
592
}
561
593
562
fn runCommand(raw_cmd: []const u8, allocator: *std.mem.Allocator) ![]const u8 {
563
    const cmd = std.mem.trim(u8, std.mem.sliceTo(raw_cmd, 0), &std.ascii.spaces);
564
    const argv = if (std.mem.startsWith(u8, cmd, "go "))
565
        &[_][]const u8{ "go", "doc", cmd[3..] }
566
    else if (std.mem.startsWith(u8, cmd, "py "))
567
        &[_][]const u8{ "python", "-c", try std.fmt.allocPrint(allocator, "import {s}; help({s});", .{ std.mem.sliceTo(cmd["py ".len..], '.'), cmd["py ".len..] }) }
568
    else if (std.mem.endsWith(u8, cmd, " --help"))
569
        // TODO: handle --help that outputs on stderr
570
        &[_][]const u8{ cmd[0..(cmd.len - " --help".len)], "--help" }
571
    else if (std.mem.startsWith(u8, cmd, "man "))
572
        // TODO: handle `man 5 sway`
573
        &[_][]const u8{ "man", cmd["man ".len..] }
574
    else if (std.mem.startsWith(u8, cmd, "s "))
575
        &[_][]const u8{ "ag", cmd["s ".len..], "/home/luna/t/raylib/src", "/home/luna/k/the-thing/resources/ode-build/include" }
576
    else if (cmd.len > 0 and std.ascii.isDigit(cmd[0]))
577
        &[_][]const u8{ "qalc", "-terse", cmd }
578
    else
579
        &[_][]const u8{ "bash", "-c", cmd };
580
    for (argv) |arg| {
581
        std.debug.print("'{s}' ", .{arg});
582
    }
583
    const result = try std.ChildProcess.exec(.{ .allocator = allocator, .argv = argv, .max_output_bytes = 1024 * 1024 });
584
    std.debug.print("stdout: '{s}'\n", .{result.stdout[0..std.math.min(100, result.stdout.len)]});
585
    std.debug.print("stderr: '{s}'\n", .{result.stderr});
586
587
    if (result.stdout.len > 0) {
588
        allocator.free(result.stderr);
589
        return result.stdout;
590
    } else if (result.stderr.len > 0) {
591
        allocator.free(result.stdout);
592
        return result.stderr;
593
    } else {
594
        allocator.free(result.stdout);
595
        allocator.free(result.stderr);
596
        return std.fmt.allocPrint(allocator, "<no output>", .{});
597
    }
598
}
599
600
// tests
594
// tests
601
595
602
test "trim []const u8" {
596
test "trim []const u8" {