From ccb1cea49a600204e0261a045fbbedc4be2e2f75 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Tue, 24 Oct 2023 20:55:29 -0700 Subject: [PATCH] inspector: filter terminal io events by kind --- src/inspector/Inspector.zig | 64 +++++++++++++++++++++++++++++++++---- src/inspector/termio.zig | 11 ++++++- src/terminal/Parser.zig | 2 ++ 3 files changed, 70 insertions(+), 7 deletions(-) diff --git a/src/inspector/Inspector.zig b/src/inspector/Inspector.zig index 5caa5d0a3..1043bff31 100644 --- a/src/inspector/Inspector.zig +++ b/src/inspector/Inspector.zig @@ -1093,17 +1093,69 @@ fn renderTermioWindow(self: *Inspector) void { )) return; list: { + const popup_filter = "Filter"; + if (cimgui.c.igButton("Filter", .{ .x = 0, .y = 0 })) { + cimgui.c.igOpenPopup_Str( + popup_filter, + cimgui.c.ImGuiPopupFlags_None, + ); + } + + if (cimgui.c.igBeginPopupModal( + popup_filter, + null, + cimgui.c.ImGuiWindowFlags_AlwaysAutoResize, + )) { + defer cimgui.c.igEndPopup(); + + cimgui.c.igText("Selected filters will only affect future events."); + cimgui.c.igSeparator(); + + { + _ = cimgui.c.igBeginTable( + "table_filter_kind", + 3, + cimgui.c.ImGuiTableFlags_None, + .{ .x = 0, .y = 0 }, + 0, + ); + defer cimgui.c.igEndTable(); + + inline for (@typeInfo(terminal.Parser.Action.Tag).Enum.fields) |field| { + const tag = @field(terminal.Parser.Action.Tag, field.name); + if (tag == .apc_put or tag == .dcs_put) continue; + + _ = cimgui.c.igTableNextColumn(); + var value = !self.vt_stream.handler.filter_exclude.contains(tag); + if (cimgui.c.igCheckbox(@tagName(tag).ptr, &value)) { + if (value) { + self.vt_stream.handler.filter_exclude.insert(tag); + } else { + self.vt_stream.handler.filter_exclude.remove(tag); + } + } + } + } // Filter kind table + + if (cimgui.c.igButton("Close", .{ .x = 0, .y = 0 })) { + cimgui.c.igCloseCurrentPopup(); + } + } // filter popup + + if (!self.vt_events.empty()) { + cimgui.c.igSameLine(0, cimgui.c.igGetStyle().*.ItemInnerSpacing.x); + if (cimgui.c.igButton("Clear", .{ .x = 0, .y = 0 })) { + var it = self.vt_events.iterator(.forward); + while (it.next()) |v| v.deinit(self.surface.alloc); + self.vt_events.clear(); + } + } + if (self.vt_events.empty()) { cimgui.c.igText("Waiting for events..."); break :list; } - if (cimgui.c.igButton("Clear", .{ .x = 0, .y = 0 })) { - var it = self.vt_events.iterator(.forward); - while (it.next()) |v| v.deinit(self.surface.alloc); - self.vt_events.clear(); - } - cimgui.c.igSeparator(); _ = cimgui.c.igBeginTable( diff --git a/src/inspector/termio.zig b/src/inspector/termio.zig index 0b3073001..ac67123f4 100644 --- a/src/inspector/termio.zig +++ b/src/inspector/termio.zig @@ -57,16 +57,25 @@ const Handler = struct { /// of the inspector because this is pointer-stable. surface: *Surface, + /// Exclude certain actions by tag. + filter_exclude: ActionTagSet = ActionTagSet.initMany(&.{.print}), + + const ActionTagSet = std.EnumSet(terminal.Parser.Action.Tag); + /// This is called with every single terminal action. pub fn handleManually(self: *Handler, action: terminal.Parser.Action) !bool { const insp = self.surface.inspector orelse return false; // We ignore certain action types that are too noisy. switch (action) { - .dcs_put, .apc_put => return false, + .dcs_put, .apc_put => return true, else => {}, } + // If we requested a specific type to be ignored, ignore it. + // We return true because we did "handle" it by ignoring it. + if (self.filter_exclude.contains(std.meta.activeTag(action))) return true; + const alloc = self.surface.alloc; const ev = try VTEvent.init(alloc, action); diff --git a/src/terminal/Parser.zig b/src/terminal/Parser.zig index 154dfee22..639063d0c 100644 --- a/src/terminal/Parser.zig +++ b/src/terminal/Parser.zig @@ -54,6 +54,8 @@ pub const TransitionAction = enum { /// Action is the action that a caller of the parser is expected to /// take as a result of some input character. pub const Action = union(enum) { + pub const Tag = std.meta.FieldEnum(Action); + /// Draw character to the screen. This is a unicode codepoint. print: u21,