aboutsummaryrefslogtreecommitdiff
path: root/vendor/libghostty-vt/src/inspector/widgets/termio.zig
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-09-10 21:51:57 +0300
committerGitHub <noreply@github.com>2026-09-10 21:51:57 +0300
commit425c86179791cd32e2d4ce0ae7f269940b4b0663 (patch)
treee52c4383a6d69216cbe2a32638bf90841d7e2189 /vendor/libghostty-vt/src/inspector/widgets/termio.zig
parent90e947a6e26e02f10ec7f1694c4eb5b78a86406b (diff)
chore: upgrade libghostty and preserve terminal behavior (#3906)
Diffstat (limited to 'vendor/libghostty-vt/src/inspector/widgets/termio.zig')
-rw-r--r--vendor/libghostty-vt/src/inspector/widgets/termio.zig89
1 files changed, 85 insertions, 4 deletions
diff --git a/vendor/libghostty-vt/src/inspector/widgets/termio.zig b/vendor/libghostty-vt/src/inspector/widgets/termio.zig
index b721d942..2c94b1bf 100644
--- a/vendor/libghostty-vt/src/inspector/widgets/termio.zig
+++ b/vendor/libghostty-vt/src/inspector/widgets/termio.zig
@@ -7,6 +7,8 @@ const CircBuf = @import("../../datastruct/main.zig").CircBuf;
const Surface = @import("../../Surface.zig");
const screen = @import("screen.zig");
+const log = std.log.scoped(.inspector_terminal_io);
+
/// VT event stream inspector widget.
pub const Stream = struct {
events: VTEvent.Ring,
@@ -30,7 +32,10 @@ pub const Stream = struct {
return .{
.events = events,
- .parser_stream = .initAlloc(alloc, handler),
+ .parser_stream = .init(.{
+ .allocator = alloc,
+ .handler = handler,
+ }),
};
}
@@ -59,9 +64,10 @@ pub const Stream = struct {
pub fn draw(
self: *Stream,
- alloc: Allocator,
+ surface: *Surface,
palette: *const terminal.color.Palette,
) void {
+ const alloc = surface.alloc;
const events = &self.events;
const handler = &self.parser_stream.handler;
const popup_filter = "Filter";
@@ -93,6 +99,16 @@ pub const Stream = struct {
handler.current_seq = 1;
}
+
+ cimgui.c.ImGui_SameLineEx(0, cimgui.c.ImGui_GetStyle().*.ItemInnerSpacing.x);
+ if (cimgui.c.ImGui_Button("Copy")) {
+ self.copyEvents(surface);
+ }
+
+ cimgui.c.ImGui_SameLineEx(0, cimgui.c.ImGui_GetStyle().*.ItemInnerSpacing.x);
+ if (cimgui.c.ImGui_Button("Export to file")) {
+ self.exportEvents(surface);
+ }
}
}
@@ -330,6 +346,73 @@ pub const Stream = struct {
}
} // filter popup
}
+
+ /// Copy all recorded events to the standard clipboard in chronological
+ /// order.
+ fn copyEvents(
+ self: *const Stream,
+ surface: *Surface,
+ ) void {
+ const alloc = surface.alloc;
+ const contents = self.formatEvents(alloc) catch |err| {
+ log.err("failed to format terminal IO events for copy err={}", .{err});
+ return;
+ };
+ defer alloc.free(contents);
+
+ surface.rt_surface.setClipboard(.standard, &.{.{
+ .mime = "text/plain",
+ .data = contents,
+ }}, false) catch |err| {
+ log.err("failed to copy terminal IO events err={}", .{err});
+ };
+ }
+
+ /// Ask the application runtime to save all recorded events to a file.
+ fn exportEvents(
+ self: *const Stream,
+ surface: *Surface,
+ ) void {
+ const alloc = surface.alloc;
+ const contents = self.formatEvents(alloc) catch |err| {
+ log.err("failed to format terminal IO events for export err={}", .{err});
+ return;
+ };
+ defer alloc.free(contents);
+
+ const handled = surface.rt_app.performAction(
+ .{ .surface = surface },
+ .export_terminal_io,
+ .{ .contents = contents },
+ ) catch |err| {
+ log.err("failed to export terminal IO events err={}", .{err});
+ return;
+ };
+ if (!handled) {
+ log.warn("application runtime does not support exporting terminal IO events", .{});
+ }
+ }
+
+ /// Format all recorded events as tab-separated text. Events are exported
+ /// oldest-first even though the inspector displays the newest event first.
+ fn formatEvents(
+ self: *const Stream,
+ alloc: Allocator,
+ ) ![:0]u8 {
+ var buf: std.Io.Writer.Allocating = .init(alloc);
+ errdefer buf.deinit();
+
+ try buf.writer.writeAll("Seq\tKind\tDescription\n");
+ var it = self.events.iterator(.forward);
+ while (it.next()) |ev| {
+ try buf.writer.print(
+ "{d}\t{s}\t{s}\n",
+ .{ ev.seq, @tagName(ev.kind), ev.raw_description },
+ );
+ }
+
+ return try buf.toOwnedSliceSentinel(0);
+ }
};
/// Helper function to check keyboard state and determine navigation action.
@@ -793,8 +876,6 @@ const VTHandler = struct {
vt_events.deleteOldest(1);
try vt_events.append(ev);
},
-
- else => return err,
};
// Do NOT skip it, because we want to record more information