summaryrefslogtreecommitdiff
path: root/main.zig
diff options
context:
space:
mode:
Diffstat (limited to 'main.zig')
-rw-r--r--main.zig141
1 files changed, 109 insertions, 32 deletions
diff --git a/main.zig b/main.zig
index a6027b0c..60bc1290 100644
--- a/main.zig
+++ b/main.zig
@@ -14,6 +14,8 @@ extern "c" fn execvp(
argv: [*:null]const ?[*:0]const u8,
) c_int;
+extern "c" fn _exit(status: c_int) noreturn;
+
// basic file navigation
// basic shell io
// basic layouting: for now following acme and ad
@@ -32,6 +34,7 @@ pub const Command = struct {
quit,
tick,
key_press: vaxis.Key,
+ pty_read: []u8,
winsize: vaxis.Winsize,
mouse: vaxis.Mouse,
} = .nop;
@@ -51,8 +54,9 @@ fn fork_pty(argv: [:0]const u8, ws: std.posix.winsize) std.Io.File {
var master: c_int = undefined;
const pid = forkpty(&master, null, null, &ws);
if (pid == 0) {
- _ = execvp(argv, &.{});
- std.process.exit(0);
+ const child_argv = [_:null]?[*:0]const u8{ argv.ptr, null };
+ _ = execvp(argv.ptr, &child_argv);
+ _exit(127);
}
// not sure about the false here
@@ -60,8 +64,23 @@ fn fork_pty(argv: [:0]const u8, ws: std.posix.winsize) std.Io.File {
return f;
}
-const nrows = 16;
-const ncols = 80;
+fn readPty(io: std.Io, gpa: std.mem.Allocator, pty: std.Io.File, loop: *Loop) !void {
+ var read_buf: [0x1000]u8 = undefined;
+ var reader = pty.readerStreaming(io, &read_buf);
+ while (true) {
+ var buf: [0x1000]u8 = undefined;
+ var vec = [_][]u8{&buf};
+ const n = try reader.interface.readVec(&vec);
+ if (n == 0) break;
+ const bytes = try gpa.dupe(u8, buf[0..n]);
+ errdefer gpa.free(bytes);
+ try loop.postEvent(.{ .pty_read = bytes });
+ }
+ try loop.postEvent(.quit);
+}
+
+const nrows = 64;
+const ncols = 100;
pub fn main(init: std.process.Init) !void {
const io = init.io;
@@ -72,10 +91,8 @@ pub fn main(init: std.process.Init) !void {
.rows = nrows,
});
defer term.deinit(gpa);
- var tty_reader = term.vtStream();
- defer tty_reader.deinit();
-
- // const str = try term.plainString(gpa);
+ var term_stream = term.vtStream();
+ defer term_stream.deinit();
var tty_buf: [0x10000]u8 = undefined;
@@ -94,50 +111,110 @@ pub fn main(init: std.process.Init) !void {
var write_buf: [0x100]u8 = undefined;
var writer = pty_master.writer(io, &write_buf);
- std.debug.print("written {}\n", .{try writer.interface.write("ls -la /\r\n")});
+ std.debug.print("written {}\n", .{try writer.interface.write("ls /\r\n")});
try writer.flush();
- var read_buf: [0x400]u8 = undefined;
- var reader = pty_master.readerStreaming(io, &read_buf);
-
- try io.sleep(.fromMilliseconds(200), .real);
- const str = try reader.interface.readAlloc(gpa, 0x400);
-
- tty_reader.nextSlice(str);
-
- defer gpa.free(str);
-
- const tty_str = try term.plainString(gpa);
- defer gpa.free(tty_str);
-
- // std.debug.print("{s}", .{tty_str});
-
- // try vx.setMouseMode(tty.writer(), true);
+ try vx.setMouseMode(tty.writer(), true);
+ try vx.enterAltScreen(tty.writer());
+ defer vx.exitAltScreen(tty.writer()) catch {};
var loop: Loop = .init(io, &tty, &vx);
try loop.start();
defer loop.stop();
+ var pty_reader = try io.concurrent(readPty, .{ io, gpa, pty_master, &loop });
+ defer _ = pty_reader.cancel(io) catch {};
+ defer pty_master.close(io);
+ var dbg_print_buf: [0x1000]u8 = undefined;
+
while (true) {
const event = try loop.nextEvent();
const win = vx.window();
- const win_child = win.child(.{
- .border = .{ .where = .all },
- .height = nrows,
- .width = ncols,
- });
- _ = win_child.printSegment(.{ .text = tty_str }, .{});
-
switch (event) {
+ .mouse => |mouse| {
+ if (mouse.button == .wheel_down) {
+ term.screens.active.scroll(.{ .delta_row = 1 });
+ }
+
+ if (mouse.button == .wheel_up) {
+ term.screens.active.scroll(.{ .delta_row = -1 });
+ }
+ },
.key_press => |key| {
if (key.matches('c', .{ .ctrl = true })) {
break;
}
+
+ if (key.matches('k', .{ .ctrl = true })) {
+ win.clear();
+ }
+
+ // this is not what I expected; it's just blank up or down
+ // if (key.matches('d', .{ .ctrl = true })) {
+ // try term.scrollUp(1);
+ // }
+
+ if (key.matches('d', .{ .ctrl = true })) {
+ term.screens.active.scroll(.{ .delta_row = 15 });
+ }
+ if (key.matches('u', .{ .ctrl = true })) {
+ term.screens.active.scroll(.{ .delta_row = -15 });
+ }
+
+ if (key.text) |text| {
+ try writer.interface.writeAll(text);
+ } else switch (key.codepoint) {
+ vaxis.Key.enter => try writer.interface.writeAll("\r"),
+ vaxis.Key.backspace => try writer.interface.writeAll("\x7f"),
+ vaxis.Key.tab => try writer.interface.writeAll("\t"),
+ vaxis.Key.escape => try writer.interface.writeAll("\x1b"),
+ vaxis.Key.up => try writer.interface.writeAll("\x1b[A"),
+ vaxis.Key.down => try writer.interface.writeAll("\x1b[B"),
+ vaxis.Key.right => try writer.interface.writeAll("\x1b[C"),
+ vaxis.Key.left => try writer.interface.writeAll("\x1b[D"),
+ else => {},
+ }
+ try writer.flush();
+ },
+ .pty_read => |bytes| {
+ defer gpa.free(bytes);
+ term_stream.nextSlice(bytes);
},
.winsize => |ws| try vx.resize(gpa, tty.writer(), ws),
+ .quit => break,
else => {},
}
+ // term.scrollViewport(.bottom);
+ const tty_str = try term.plainString(gpa);
+ defer gpa.free(tty_str);
+
+ const win_child = win.child(.{
+ .border = .{ .where = .bottom },
+ .height = nrows + 2,
+ .width = ncols + 2,
+ });
+ const win_dbg = win.child(.{
+ .border = .{ .where = .all },
+ .x_off = ncols + 2,
+ .height = nrows + 2,
+ .width = ncols + 2,
+ });
+
+ win_child.clear();
+ _ = win_child.printSegment(.{ .text = tty_str }, .{});
+ win_child.showCursor(term.screens.active.cursor.x, term.screens.active.cursor.y);
+
+ const dbg_str = try std.fmt.bufPrintSentinel(
+ &dbg_print_buf,
+ "c {} {}\npty pid {}\nwow it's working! debugging things will show here",
+ .{
+ pty_master.handle, term.screens.active.cursor.x, term.screens.active.cursor.y,
+ },
+ 0,
+ );
+ _ = win_dbg.printSegment(.{ .text = dbg_str }, .{});
+
try vx.render(tty.writer());
}
}