summaryrefslogtreecommitdiff
path: root/main.zig
diff options
context:
space:
mode:
Diffstat (limited to 'main.zig')
-rw-r--r--main.zig83
1 files changed, 78 insertions, 5 deletions
diff --git a/main.zig b/main.zig
index 5d8cb228..5d604460 100644
--- a/main.zig
+++ b/main.zig
@@ -115,8 +115,13 @@ pub fn main(init: std.process.Init) !void {
var term_stream = term.vtStream();
defer term_stream.deinit();
- var tty_buf: [0x10000]u8 = undefined;
+ var selection_start_col: ?i32 = null;
+ var selection_end_col: ?i32 = null;
+ var selection_start_row: ?i32 = null;
+ var selection_end_row: ?i32 = null;
+ var selection_state: enum { done, dragging, none } = .none;
+ var tty_buf: [0x10000]u8 = undefined;
var tty = try vaxis.Tty.init(io, &tty_buf);
var vx = try vaxis.init(io, gpa, init.environ_map, .{});
@@ -174,11 +179,36 @@ pub fn main(init: std.process.Init) !void {
term.screens.active.scroll(.{ .delta_row = -(mouse.row) });
}
- if (mouse.button == .left and mouse.col > term_x_padding) {}
-
if (mouse.button == .right and mouse.col <= term_x_padding) {
term.screens.active.scroll(.{ .delta_row = mouse.row });
}
+
+ // selection
+ if (mouse.button == .left and mouse.col > term_x_padding) {
+ selection_start_col = mouse.col;
+ selection_start_row = mouse.row + @as(
+ i32,
+ @intCast(term.screens.active.pages.scrollbar().offset),
+ );
+ selection_state = .dragging;
+ }
+ }
+
+ if (mouse.type == .drag and selection_state == .dragging and mouse.col > term_x_padding) {
+ selection_end_col = mouse.col;
+ selection_end_row = mouse.row + @as(
+ i32,
+ @intCast(term.screens.active.pages.scrollbar().offset),
+ );
+ }
+
+ if (mouse.type == .release and mouse.col > term_x_padding) {
+ selection_end_col = mouse.col;
+ selection_end_row = mouse.row + @as(
+ i32,
+ @intCast(term.screens.active.pages.scrollbar().offset),
+ );
+ selection_state = .done;
}
},
.key_press => |key| {
@@ -288,13 +318,52 @@ pub fn main(init: std.process.Init) !void {
});
win_child.clear();
- _ = win_child.printSegment(.{ .text = tty_str }, .{});
+
+ // _ = win_child.printSegment(.{ .text = tty_str }, .{});
+ // Selection rectangle in win_child-local space: rows carry the scroll
+ // offset; cols are window-relative, so shift left by term_x_padding to
+ // land inside win_child (x_off = term_x_padding).
+ const off: i32 = @intCast(term.screens.active.pages.scrollbar().offset);
+ const sel: ?struct { r0: i32, r1: i32, c0: i32, c1: i32 } = blk: {
+ if (selection_state == .none) break :blk null;
+ const sr = selection_start_row orelse break :blk null;
+ const er = selection_end_row orelse break :blk null;
+ const sc = selection_start_col orelse break :blk null;
+ const ec = selection_end_col orelse break :blk null;
+ break :blk .{
+ .r0 = @min(sr, er),
+ .r1 = @max(sr, er),
+ .c0 = @min(sc, ec) - term_x_padding,
+ .c1 = @max(sc, ec) - term_x_padding,
+ };
+ };
+
+ var lines_it = std.mem.splitAny(u8, tty_str, "\n");
+ {
+ var i: u16 = 0;
+ while (lines_it.next()) |line| : (i += 1) {
+ const j = @as(i32, i) + off;
+ if (sel) |s| if (j >= s.r0 and j <= s.r1) {
+ // ponytail: byte index == column (ASCII); wide chars misalign.
+ const b0 = @min(@as(usize, @intCast(@max(0, s.c0))), line.len);
+ const b1 = @min(@as(usize, @intCast(@max(0, s.c1 + 1))), line.len);
+ _ = win_child.print(&.{
+ .{ .text = line[0..b0] },
+ .{ .text = line[b0..b1], .style = .{ .bg = .{ .index = 4 }, .fg = .{ .index = 3 } } },
+ .{ .text = line[b1..] },
+ }, .{ .row_offset = i });
+ continue;
+ };
+ _ = win_child.printSegment(.{ .text = line }, .{ .row_offset = i });
+ }
+ }
+
win_child.showCursor(term.screens.active.cursor.x, term.screens.active.cursor.y);
const pty_ws = pty_get_size(pty_master);
const dbg_str = try std.fmt.bufPrintSentinel(
&dbg_print_buf,
- "c {} {}\npty pid {}\n grid {}x{} pty {}x{}\n resizes={}\n scroll {}/{} vis: {}\n",
+ "c {} {}\npty pid {}\n grid {}x{} pty {}x{}\n resizes={}\n scroll {}/{} vis: {}\n{} -> {}, {} -> {}",
.{
pty_master.handle,
term.screens.active.cursor.x,
@@ -307,6 +376,10 @@ pub fn main(init: std.process.Init) !void {
term.screens.active.pages.scrollbar().offset,
term.screens.active.pages.scrollbar().total,
term.screens.active.pages.scrollbar().len,
+ selection_start_col orelse 0,
+ selection_end_col orelse 0,
+ selection_start_row orelse 0,
+ selection_end_row orelse 0,
},
0,
);