summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Schneider <[email protected]>2026-06-13 22:26:03 -0300
committerGabriel Schneider <[email protected]>2026-06-25 11:23:20 -0300
commit7e3240817c888ec3fa4c553cd77695e8d106598f (patch)
treeb4bee2bee9d6dd2c008ad5eae5ba5f840beb67c5
downloadpardes-7e3240817c888ec3fa4c553cd77695e8d106598f.tar.gz
pardes-7e3240817c888ec3fa4c553cd77695e8d106598f.zip
day-00: basic mouse and showing cwd relative fs
-rw-r--r--.gitignore4
-rw-r--r--build.zig27
-rw-r--r--build.zig.zon13
-rw-r--r--dbg.txt25
-rw-r--r--ideas.typ13
-rw-r--r--main.zig122
-rw-r--r--mise.toml2
7 files changed, 206 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..4a6692ad
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+zig-pkg
+zig-out
+.zig-cache/
+.zig-cache/*
diff --git a/build.zig b/build.zig
new file mode 100644
index 00000000..14066cf3
--- /dev/null
+++ b/build.zig
@@ -0,0 +1,27 @@
+const std = @import("std");
+
+pub fn build(b: *std.Build) void {
+ const optimize = b.standardOptimizeOption(.{});
+ const target = b.standardTargetOptions(.{});
+
+ const vaxis_dep = b.dependency("vaxis", .{
+ .target = target,
+ .optimize = optimize,
+ });
+
+ const exe = b.addExecutable(.{
+ .name = "pardes",
+ .root_module = b.createModule(.{
+ .target = target,
+ .optimize = optimize,
+ .root_source_file = b.path("main.zig"),
+ }),
+ });
+
+ exe.root_module.addImport("vaxis", vaxis_dep.module("vaxis"));
+
+ const run_exe = b.addRunArtifact(exe);
+
+ const run = b.step("run", "descend to the pardes");
+ run.dependOn(&run_exe.step);
+}
diff --git a/build.zig.zon b/build.zig.zon
new file mode 100644
index 00000000..4c7fb6e7
--- /dev/null
+++ b/build.zig.zon
@@ -0,0 +1,13 @@
+.{
+ .name = ._02_pardes_code,
+ .version = "0.0.1",
+ .dependencies = .{
+ .vaxis = .{
+ .url = "git+https://github.com/rockorager/libvaxis.git#a367b89da09bfe5e1b628501940de5b4f858f5f3",
+ .hash = "vaxis-0.6.0-BWNV_HHwCQB451KS7A8SMykALblPmGwHnzSfiJHjN3_9",
+ },
+ },
+ .minimum_zig_version = "0.16.0",
+ .paths = .{""},
+ .fingerprint = 0x7d072ef9f9841c0d,
+}
diff --git a/dbg.txt b/dbg.txt
new file mode 100644
index 00000000..076a07cc
--- /dev/null
+++ b/dbg.txt
@@ -0,0 +1,25 @@
+hello!
+error: FileNotFound
+/usr/lib/zig/std/Io/Threaded.zig:1434:9: 0x11809a3 in fail__anon_24261 (std.zig)
+ return err;
+ ^
+/usr/lib/zig/std/Io/Threaded.zig:5292:23: 0x11a5a7a in dirOpenDirPosix (std.zig)
+ .NOENT => return syscall.fail(error.FileNotFound),
+ ^
+/usr/lib/zig/std/Io/Dir.zig:482:5: 0x11ac29a in openDir (std.zig)
+ return io.vtable.dirOpenDir(io.userdata, dir, sub_path, options);
+ ^
+/home/goblin/00-projects/02-pardes-code/main.zig:47:17: 0x1208335 in main (main.zig)
+ const cwd = try std.Io.Dir.openDir(dir, io, "", .{ .iterate = true });
+ ^
+run
++- run exe pardes failure
+error: process exited with error code 1
+failed command: ./.zig-cache/o/605d89fea3f4d2723007022f57b9e214/pardes
+
+Build Summary: 4/6 steps succeeded (1 failed)
+run transitive failure
++- run exe pardes failure
+
+error: the following build command failed with exit code 1:
+.zig-cache/o/bc886f30ac2e1c5536b489917da9cbab/build /usr/bin/zig /usr/lib/zig /home/goblin/00-projects/02-pardes-code .zig-cache /home/goblin/.cache/zig --seed 0x488ca716 -Z27dadd76006b2149 run
diff --git a/ideas.typ b/ideas.typ
new file mode 100644
index 00000000..f4faf810
--- /dev/null
+++ b/ideas.typ
@@ -0,0 +1,13 @@
+- grep shows treesitter context around
+ - this could be implemented as a separate binary
+- clickable file:lines show somehow (as highlights or something else)
+ - is line above of below middle one on the editor
+ - is this on the same file as open on the editor
+
+- clickable things for the mouse should be navigatable with the keyboard
+ - like if I get some search results I can just use tab to navigate them, the editor should know:
+ - semantic boundaries (maybe just jump to the next clickable thing?)
+
+- undo for everything?
+ - I want search results in general to be logged, that's one of the reasons why the tty is a good fit
+ - so it'd be cool to undo that too?
diff --git a/main.zig b/main.zig
new file mode 100644
index 00000000..e591b7d0
--- /dev/null
+++ b/main.zig
@@ -0,0 +1,122 @@
+const std = @import("std");
+const vaxis = @import("vaxis");
+
+// basic file navigation
+// basic shell io
+// basic layouting: for now following acme and ad
+// * /home/goblin/05-genizah/plan9port/src/cmd/acme
+// * /home/goblin/05-genizah/ad
+// * /usr/lib/zig
+// * ../03-plano
+// right click and enter on lines to open files at specified lines
+
+pub const Command = struct {
+ prev: ?*Command = null,
+ pub var value: union(enum) {
+ close,
+ ping,
+ nop,
+ quit,
+ tick,
+ key_press: vaxis.Key,
+ winsize: vaxis.Winsize,
+ mouse: vaxis.Mouse,
+ } = .nop;
+};
+
+const Loop = vaxis.Loop(@TypeOf(Command.value));
+const MAX_FILES: usize = 0x200;
+
+fn ticker(io: std.Io, loop: *Loop) void {
+ while (true) {
+ io.sleep(.fromMilliseconds(2), .awake) catch return;
+ _ = loop.tryPostEvent(.tick) catch return;
+ }
+}
+
+pub fn main(init: std.process.Init) !void {
+ std.debug.print("hello!\n", .{});
+
+ const io = init.io;
+ const gpa = init.gpa;
+
+ var tty_buf: [0x10000]u8 = undefined;
+ var lines: [0x1000][0x1000]u8 = undefined;
+
+ const dir = std.Io.Dir.cwd();
+ const cwd = try std.Io.Dir.openDir(dir, io, ".", .{ .iterate = true });
+ var walk = try cwd.walk(gpa);
+ defer walk.deinit();
+
+ {
+ var i: usize = 0;
+
+ while (try walk.next(io)) |e| : (i += 1) {
+ if (i > MAX_FILES) break;
+
+ std.debug.print("path: {s}\n", .{e.path});
+ @memcpy(lines[i][0..e.path.len], e.path);
+ std.debug.dumpHex(lines[i][0..2]);
+ lines[i][e.path.len] = 0;
+ }
+ }
+
+ var tty = try vaxis.Tty.init(io, &tty_buf);
+
+ var vx = try vaxis.init(io, gpa, init.environ_map, .{});
+ defer vx.deinit(gpa, tty.writer());
+
+ try vx.enterAltScreen(tty.writer());
+ defer vx.exitAltScreen(tty.writer()) catch {};
+
+ try vx.setMouseMode(tty.writer(), true);
+
+ var loop: Loop = .init(io, &tty, &vx);
+ try loop.start();
+ defer loop.stop();
+
+ while (true) {
+ const event = try loop.nextEvent();
+ const win = vx.window();
+
+ for (0..MAX_FILES) |i| {
+ if (i > MAX_FILES) break;
+
+ // const str: [:0]u8 = std.mem.absorbSentinel(&line);
+ const len = std.mem.findSentinel(u8, 0, @ptrCast(&lines[i]));
+ _ = win.printSegment(.{ .text = lines[i][0..len] }, .{
+ .row_offset = @intCast(i),
+ .wrap = .none,
+ });
+ }
+
+ switch (event) {
+ .key_press => |key| {
+ if (key.matches('c', .{ .ctrl = true })) {
+ break;
+ }
+ },
+ .mouse => |m| {
+ if (m.type == .press) {
+ // const txt = try std.fmt.allocPrint(gpa, "col={} row={} xo={} yo={}", .{ m.col, m.row, m.xoffset, m.yoffset });
+ const len = std.mem.findSentinel(u8, 0, @ptrCast(&lines[@intCast(m.row)]));
+ _ = win.printSegment(
+ .{
+ .text = lines[@intCast(m.row)][0..len],
+ .style = .{ .fg = .{ .rgb = .{ 0x00, 0xd0, 0xaa } } },
+ },
+ .{
+ .col_offset = @as(u16, @intCast(m.col)),
+ .row_offset = @as(u16, @intCast(m.row)),
+ .wrap = .none,
+ },
+ );
+ }
+ },
+ .winsize => |ws| try vx.resize(gpa, tty.writer(), ws),
+ else => {},
+ }
+
+ try vx.render(tty.writer());
+ }
+}
diff --git a/mise.toml b/mise.toml
new file mode 100644
index 00000000..bf78ddc6
--- /dev/null
+++ b/mise.toml
@@ -0,0 +1,2 @@
+[tools]
+zls = "0.16"