summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.zig175
1 files changed, 51 insertions, 124 deletions
diff --git a/main.zig b/main.zig
index 13450063..620bdede 100644
--- a/main.zig
+++ b/main.zig
@@ -31,41 +31,23 @@ extern "c" fn _exit(status: c_int) noreturn;
// * ../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,
- pty_read: []u8,
- winsize: vaxis.Winsize,
- mouse: vaxis.Mouse,
- } = .nop;
+const Event = union(enum) {
+ quit,
+ key_press: vaxis.Key,
+ pty_read: []u8,
+ winsize: vaxis.Winsize,
+ mouse: vaxis.Mouse,
};
-const Loop = vaxis.Loop(@TypeOf(Command.value));
+const Loop = vaxis.Loop(Event);
const MAX_LINES: usize = 0x1000;
const MAX_LINE_LEN: usize = 0x200;
const MAX_HISTORY: usize = 0x100;
const FILE_PANE: usize = 0;
const TTY_PANE: usize = 1;
-const TS_COMMENT: u8 = 1;
-const TS_STRING: u8 = 2;
-const TS_NUMBER: u8 = 3;
-const TS_KEYWORD: u8 = 4;
-const TS_TYPE: u8 = 5;
-const TS_FUNCTION: u8 = 6;
-const TS_BUILTIN: u8 = 7;
-
-fn ticker(io: std.Io, loop: *Loop) void {
- while (true) {
- io.sleep(.fromMilliseconds(2), .awake) catch return;
- _ = loop.tryPostEvent(.tick) catch return;
- }
-}
+const TS_STRING: u8 = 1;
+const TS_NUMBER: u8 = 2;
+const TS_KEYWORD: u8 = 3;
fn fork_pty(argv: [:0]const u8, ws: std.posix.winsize) std.Io.File {
var master: c_int = undefined;
@@ -96,41 +78,18 @@ fn readPty(io: std.Io, gpa: std.mem.Allocator, pty: std.Io.File, loop: *Loop) !v
try loop.postEvent(.quit);
}
-fn putLine(lines: *[MAX_LINES][MAX_LINE_LEN]u8, idx: usize, text: []const u8) void {
- const len = @min(text.len, MAX_LINE_LEN - 1);
- @memcpy(lines[idx][0..len], text[0..len]);
- lines[idx][len] = 0;
-}
-
-fn putString(buf: *[MAX_LINE_LEN]u8, text: []const u8) usize {
- const len = @min(text.len, MAX_LINE_LEN - 1);
- @memcpy(buf[0..len], text[0..len]);
- buf[len] = 0;
- return len;
-}
-
fn pathFrom(base: []const u8, name: []const u8, buf: *[MAX_LINE_LEN]u8) []const u8 {
- if (std.fs.path.isAbsolute(name)) {
- const len = putString(buf, name);
- return buf[0..len];
- }
-
- return std.fmt.bufPrint(buf, "{s}/{s}", .{ base, name }) catch blk: {
- const len = putString(buf, name);
- break :blk buf[0..len];
- };
+ if (std.fs.path.isAbsolute(name)) return name;
+ return std.fmt.bufPrint(buf, "{s}/{s}", .{ base, name }) catch name;
}
-fn splitLines(lines: *[MAX_LINES][MAX_LINE_LEN]u8, text: []const u8) usize {
+// lines point into the backing text (file_text / tty_text); no copy.
+fn splitLines(lines: *[MAX_LINES][]const u8, text: []const u8) usize {
var iter = std.mem.splitScalar(u8, text, '\n');
var i: usize = 0;
while (iter.next()) |line| : (i += 1) {
if (i >= MAX_LINES) break;
- putLine(lines, i, line);
- }
- if (i == 0) {
- putLine(lines, 0, "");
- i = 1;
+ lines[i] = line;
}
return i;
}
@@ -155,23 +114,22 @@ fn loadFile(
io: std.Io,
gpa: std.mem.Allocator,
path: []const u8,
- lines: *[MAX_LINES][MAX_LINE_LEN]u8,
+ lines: *[MAX_LINES][]const u8,
rendered_lines: *usize,
- current_path: *[MAX_LINE_LEN]u8,
- current_path_len: *usize,
+ current_path_buf: *[MAX_LINE_LEN]u8,
+ current_path: *[]const u8,
file_text: *[]u8,
highlight_styles: *[MAX_LINES][MAX_LINE_LEN]u8,
) !void {
for (highlight_styles) |*row| @memset(row, 0);
- const path_len = @min(path.len, MAX_LINE_LEN - 1);
- @memcpy(current_path[0..path_len], path[0..path_len]);
- current_path[path_len] = 0;
- current_path_len.* = path_len;
+ current_path.* = std.fmt.bufPrint(current_path_buf, "{s}", .{path}) catch path;
+
+ if (file_text.*.len > 0) gpa.free(file_text.*);
+ file_text.* = &.{};
var file = std.Io.Dir.cwd().openFile(io, path, .{ .mode = .read_only }) catch |err| {
- const msg = try std.fmt.bufPrint(&lines[0], "could not open {s}: {}", .{ path, err });
- lines[0][msg.len] = 0;
- rendered_lines.* = 1;
+ file_text.* = try std.fmt.allocPrint(gpa, "could not open {s}: {}", .{ path, err });
+ rendered_lines.* = splitLines(lines, file_text.*);
return;
};
defer file.close(io);
@@ -179,15 +137,11 @@ fn loadFile(
var read_buf: [0x1000]u8 = undefined;
const flen = try file.length(io);
var reader = file.reader(io, &read_buf);
- const text = reader.interface.readAlloc(gpa, @min(flen, 0x100000)) catch |err| {
- const msg = try std.fmt.bufPrint(&lines[0], "could not read {s}: {}", .{ path, err });
- lines[0][msg.len] = 0;
- rendered_lines.* = 1;
+ file_text.* = reader.interface.readAlloc(gpa, @min(flen, 0x100000)) catch |err| {
+ file_text.* = try std.fmt.allocPrint(gpa, "could not read {s}: {}", .{ path, err });
+ rendered_lines.* = splitLines(lines, file_text.*);
return;
};
-
- if (file_text.*.len > 0) gpa.free(file_text.*);
- file_text.* = text;
rendered_lines.* = splitLines(lines, file_text.*);
var language: ?*const ts.Language = null;
@@ -225,13 +179,9 @@ fn loadFile(
for (match.captures) |capture| {
const capture_name = query.captureNameForId(capture.index) orelse "";
var style: u8 = 0;
- if (std.mem.indexOf(u8, capture_name, "comment") != null) style = TS_COMMENT;
if (std.mem.indexOf(u8, capture_name, "string") != null or std.mem.indexOf(u8, capture_name, "character") != null) style = TS_STRING;
if (std.mem.indexOf(u8, capture_name, "number") != null or std.mem.indexOf(u8, capture_name, "float") != null or std.mem.indexOf(u8, capture_name, "boolean") != null) style = TS_NUMBER;
if (std.mem.indexOf(u8, capture_name, "keyword") != null or std.mem.indexOf(u8, capture_name, "include") != null or std.mem.indexOf(u8, capture_name, "operator") != null) style = TS_KEYWORD;
- if (std.mem.indexOf(u8, capture_name, "type") != null or std.mem.indexOf(u8, capture_name, "constructor") != null) style = TS_TYPE;
- if (std.mem.indexOf(u8, capture_name, "function") != null or std.mem.indexOf(u8, capture_name, "method") != null or std.mem.indexOf(u8, capture_name, "macro") != null) style = TS_FUNCTION;
- if (std.mem.indexOf(u8, capture_name, "builtin") != null) style = TS_BUILTIN;
if (style == 0) continue;
const start = capture.node.startPoint();
@@ -322,20 +272,22 @@ pub fn main(init: std.process.Init) !void {
defer term_stream.deinit();
var tty_buf: [0x10000]u8 = undefined;
- var display_lines: [2][MAX_LINES][MAX_LINE_LEN]u8 = undefined;
+ var display_lines: [2][MAX_LINES][]const u8 = undefined;
var tty_render_lines: [MAX_LINES][MAX_LINE_LEN]u8 = undefined;
var highlight_styles: [MAX_LINES][MAX_LINE_LEN]u8 = undefined;
var file_text: []u8 = &.{};
defer if (file_text.len > 0) gpa.free(file_text);
+ var tty_text: []const u8 = &.{};
+ defer if (tty_text.len > 0) gpa.free(tty_text);
var rendered_lines = [_]usize{ 0, 0 };
var line_nums: [MAX_LINES][8]u8 = undefined;
var file_scroll: usize = 0;
- var current_path: [MAX_LINE_LEN]u8 = undefined;
- var current_path_len: usize = 0;
- var term_cwd: [MAX_LINE_LEN]u8 = undefined;
- var term_cwd_len = putString(&term_cwd, init.environ_map.get("PWD") orelse ".");
- var cwd_history: [MAX_HISTORY][MAX_LINE_LEN]u8 = undefined;
- var cwd_history_lens: [MAX_HISTORY]usize = undefined;
+ var current_path_buf: [MAX_LINE_LEN]u8 = undefined;
+ var current_path: []const u8 = "";
+ var term_cwd_buf: [MAX_LINE_LEN]u8 = undefined;
+ var term_cwd: []const u8 = init.environ_map.get("PWD") orelse ".";
+ var cwd_history_buf: [MAX_HISTORY][MAX_LINE_LEN]u8 = undefined;
+ var cwd_history: [MAX_HISTORY][]const u8 = undefined;
var cwd_history_len: usize = 0;
try loadFile(
io,
@@ -343,8 +295,8 @@ pub fn main(init: std.process.Init) !void {
if (args.len > 1) args[1] else "main.zig",
&display_lines[FILE_PANE],
&rendered_lines[FILE_PANE],
+ &current_path_buf,
&current_path,
- &current_path_len,
&file_text,
&highlight_styles,
);
@@ -419,44 +371,36 @@ pub fn main(init: std.process.Init) !void {
if (mouse.row > 0 and mouse.col >= 5) {
const line_idx = @as(usize, @intCast(mouse.row - 1)) + file_scroll;
if (line_idx < rendered_lines[FILE_PANE]) {
- const len = std.mem.findSentinel(u8, 0, @ptrCast(&display_lines[FILE_PANE][line_idx]));
const selected_col: usize = @intCast(mouse.col - 5);
- const selected_line = display_lines[FILE_PANE][line_idx][0..len];
- selected_word = extractWord(selected_line, selected_col);
+ selected_word = extractWord(display_lines[FILE_PANE][line_idx], selected_col);
}
}
} else {
const line_idx: usize = @intCast(@max(mouse.row, 0));
if (line_idx < rendered_lines[TTY_PANE]) {
- const len = std.mem.findSentinel(u8, 0, @ptrCast(&display_lines[TTY_PANE][line_idx]));
const selected_col: usize = @intCast(@max(mouse.col - right_x, 0));
- const selected_line = display_lines[TTY_PANE][line_idx][0..len];
- selected_word = extractWord(selected_line, selected_col);
+ selected_word = extractWord(display_lines[TTY_PANE][line_idx], selected_col);
}
}
if (selected_word) |word| {
if (word.len > 0) {
- var found_path_buf: [MAX_LINE_LEN]u8 = undefined;
var candidate_buf: [MAX_LINE_LEN]u8 = undefined;
var found_path: []const u8 = "";
var found_kind: ?std.Io.File.Kind = null;
- const current_candidate = pathFrom(term_cwd[0..term_cwd_len], word, &candidate_buf);
+ const current_candidate = pathFrom(term_cwd, word, &candidate_buf);
if (std.Io.Dir.cwd().statFile(io, current_candidate, .{})) |stat| {
- const found_len = putString(&found_path_buf, current_candidate);
- found_path = found_path_buf[0..found_len];
+ found_path = current_candidate;
found_kind = stat.kind;
} else |_| {}
var h = cwd_history_len;
while (found_kind == null and h > 0) {
h -= 1;
- const old_cwd = cwd_history[h][0..cwd_history_lens[h]];
- const candidate = pathFrom(old_cwd, word, &candidate_buf);
+ const candidate = pathFrom(cwd_history[h], word, &candidate_buf);
if (std.Io.Dir.cwd().statFile(io, candidate, .{})) |stat| {
- const found_len = putString(&found_path_buf, candidate);
- found_path = found_path_buf[0..found_len];
+ found_path = candidate;
found_kind = stat.kind;
} else |_| {}
}
@@ -464,10 +408,10 @@ pub fn main(init: std.process.Init) !void {
if (found_kind) |kind| {
if (kind == .directory) {
if (cwd_history_len < MAX_HISTORY) {
- cwd_history_lens[cwd_history_len] = putString(&cwd_history[cwd_history_len], term_cwd[0..term_cwd_len]);
+ cwd_history[cwd_history_len] = std.fmt.bufPrint(&cwd_history_buf[cwd_history_len], "{s}", .{term_cwd}) catch term_cwd;
cwd_history_len += 1;
}
- term_cwd_len = putString(&term_cwd, found_path);
+ term_cwd = std.fmt.bufPrint(&term_cwd_buf, "{s}", .{found_path}) catch term_cwd;
try writer.interface.writeAll("cd ");
try writer.interface.writeAll(found_path);
@@ -475,7 +419,7 @@ pub fn main(init: std.process.Init) !void {
try writer.flush();
if (!mouse_on_left) term.scrollViewport(.bottom);
} else {
- loadFile(io, gpa, found_path, &display_lines[FILE_PANE], &rendered_lines[FILE_PANE], &current_path, &current_path_len, &file_text, &highlight_styles) catch {};
+ loadFile(io, gpa, found_path, &display_lines[FILE_PANE], &rendered_lines[FILE_PANE], &current_path_buf, &current_path, &file_text, &highlight_styles) catch {};
file_scroll = 0;
}
}
@@ -525,13 +469,12 @@ pub fn main(init: std.process.Init) !void {
},
.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);
- rendered_lines[TTY_PANE] = splitLines(&display_lines[TTY_PANE], tty_str);
+ if (tty_text.len > 0) gpa.free(tty_text);
+ tty_text = try term.plainString(gpa);
+ rendered_lines[TTY_PANE] = splitLines(&display_lines[TTY_PANE], tty_text);
const win_file = win.child(.{
.border = .{ .where = .right },
@@ -543,7 +486,7 @@ pub fn main(init: std.process.Init) !void {
});
win.clear();
- _ = win_file.printSegment(.{ .text = current_path[0..current_path_len] }, .{
+ _ = win_file.printSegment(.{ .text = current_path }, .{
.row_offset = 0,
.col_offset = 5,
.wrap = .none,
@@ -553,7 +496,7 @@ pub fn main(init: std.process.Init) !void {
var i: usize = 0;
while (i < visible_lines and i + file_scroll < rendered_lines[FILE_PANE]) : (i += 1) {
const line_idx = i + file_scroll;
- const len = std.mem.findSentinel(u8, 0, @ptrCast(&display_lines[FILE_PANE][line_idx]));
+ const len = @min(display_lines[FILE_PANE][line_idx].len, MAX_LINE_LEN);
const num = try std.fmt.bufPrint(&line_nums[i], "{d:0>4}", .{line_idx + 1});
_ = win_file.printSegment(.{ .text = num }, .{
.row_offset = @intCast(i + 1),
@@ -569,10 +512,6 @@ pub fn main(init: std.process.Init) !void {
var style: vaxis.Style = .{};
var rgb = term.colors.palette.current[0];
switch (style_id) {
- TS_COMMENT => {
- rgb = term.colors.palette.current[8];
- style = .{ .fg = .{ .rgb = .{ rgb.r, rgb.g, rgb.b } }, .dim = true, .italic = true };
- },
TS_STRING => {
rgb = term.colors.palette.current[2];
style = .{ .fg = .{ .rgb = .{ rgb.r, rgb.g, rgb.b } } };
@@ -585,18 +524,6 @@ pub fn main(init: std.process.Init) !void {
rgb = term.colors.palette.current[5];
style = .{ .fg = .{ .rgb = .{ rgb.r, rgb.g, rgb.b } }, .bold = true };
},
- TS_TYPE => {
- rgb = term.colors.palette.current[6];
- style = .{ .fg = .{ .rgb = .{ rgb.r, rgb.g, rgb.b } } };
- },
- TS_FUNCTION => {
- rgb = term.colors.palette.current[4];
- style = .{ .fg = .{ .rgb = .{ rgb.r, rgb.g, rgb.b } }, .bold = true };
- },
- TS_BUILTIN => {
- rgb = term.colors.palette.current[13];
- style = .{ .fg = .{ .rgb = .{ rgb.r, rgb.g, rgb.b } } };
- },
else => {},
}
_ = win_file.printSegment(.{