mirror of
https://github.com/ghostty-org/ghostty.git
synced 2025-07-16 00:36:07 +03:00
inspector: add basic termio seq filter
This commit is contained in:
@ -115,15 +115,15 @@ pub fn init(surface: *Surface) !Inspector {
|
|||||||
var vt_events = try inspector.termio.VTEventRing.init(surface.alloc, 2);
|
var vt_events = try inspector.termio.VTEventRing.init(surface.alloc, 2);
|
||||||
errdefer vt_events.deinit(surface.alloc);
|
errdefer vt_events.deinit(surface.alloc);
|
||||||
|
|
||||||
|
var vt_handler = inspector.termio.VTHandler.init(surface);
|
||||||
|
errdefer vt_handler.deinit();
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.surface = surface,
|
.surface = surface,
|
||||||
.key_events = key_buf,
|
.key_events = key_buf,
|
||||||
.vt_events = vt_events,
|
.vt_events = vt_events,
|
||||||
.vt_stream = .{
|
.vt_stream = .{
|
||||||
.handler = .{
|
.handler = vt_handler,
|
||||||
.surface = surface,
|
|
||||||
},
|
|
||||||
|
|
||||||
.parser = .{
|
.parser = .{
|
||||||
.osc_parser = .{
|
.osc_parser = .{
|
||||||
.alloc = surface.alloc,
|
.alloc = surface.alloc,
|
||||||
@ -144,6 +144,8 @@ pub fn deinit(self: *Inspector) void {
|
|||||||
var it = self.vt_events.iterator(.forward);
|
var it = self.vt_events.iterator(.forward);
|
||||||
while (it.next()) |v| v.deinit(self.surface.alloc);
|
while (it.next()) |v| v.deinit(self.surface.alloc);
|
||||||
self.vt_events.deinit(self.surface.alloc);
|
self.vt_events.deinit(self.surface.alloc);
|
||||||
|
|
||||||
|
self.vt_stream.handler.deinit();
|
||||||
self.vt_stream.deinit();
|
self.vt_stream.deinit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1108,7 +1110,8 @@ fn renderTermioWindow(self: *Inspector) void {
|
|||||||
)) {
|
)) {
|
||||||
defer cimgui.c.igEndPopup();
|
defer cimgui.c.igEndPopup();
|
||||||
|
|
||||||
cimgui.c.igText("Selected filters will only affect future events.");
|
cimgui.c.igText("Changed filter settings will only affect future events.");
|
||||||
|
|
||||||
cimgui.c.igSeparator();
|
cimgui.c.igSeparator();
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -1137,6 +1140,20 @@ fn renderTermioWindow(self: *Inspector) void {
|
|||||||
}
|
}
|
||||||
} // Filter kind table
|
} // Filter kind table
|
||||||
|
|
||||||
|
cimgui.c.igSeparator();
|
||||||
|
|
||||||
|
cimgui.c.igText(
|
||||||
|
"Filter by string. Empty displays all, \"abc\" finds lines\n" ++
|
||||||
|
"containing \"abc\", \"abc,xyz\" finds lines containing \"abc\"\n" ++
|
||||||
|
"or \"xyz\", \"-abc\" excludes lines containing \"abc\".",
|
||||||
|
);
|
||||||
|
_ = cimgui.c.ImGuiTextFilter_Draw(
|
||||||
|
self.vt_stream.handler.filter_text,
|
||||||
|
"##filter_text",
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
|
cimgui.c.igSeparator();
|
||||||
if (cimgui.c.igButton("Close", .{ .x = 0, .y = 0 })) {
|
if (cimgui.c.igButton("Close", .{ .x = 0, .y = 0 })) {
|
||||||
cimgui.c.igCloseCurrentPopup();
|
cimgui.c.igCloseCurrentPopup();
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Allocator = std.mem.Allocator;
|
const Allocator = std.mem.Allocator;
|
||||||
|
const cimgui = @import("cimgui");
|
||||||
const terminal = @import("../terminal/main.zig");
|
const terminal = @import("../terminal/main.zig");
|
||||||
const CircBuf = @import("../circ_buf.zig").CircBuf;
|
const CircBuf = @import("../circ_buf.zig").CircBuf;
|
||||||
const Surface = @import("../Surface.zig");
|
const Surface = @import("../Surface.zig");
|
||||||
|
|
||||||
/// The stream handler for our inspector.
|
/// The stream handler for our inspector.
|
||||||
pub const Stream = terminal.Stream(Handler);
|
pub const Stream = terminal.Stream(VTHandler);
|
||||||
|
|
||||||
/// VT event circular buffer.
|
/// VT event circular buffer.
|
||||||
pub const VTEventRing = CircBuf(VTEvent, undefined);
|
pub const VTEventRing = CircBuf(VTEvent, undefined);
|
||||||
@ -49,21 +50,41 @@ pub const VTEvent = struct {
|
|||||||
pub fn deinit(self: *VTEvent, alloc: Allocator) void {
|
pub fn deinit(self: *VTEvent, alloc: Allocator) void {
|
||||||
alloc.free(self.str);
|
alloc.free(self.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns true if the event passes the given filter.
|
||||||
|
pub fn passFilter(
|
||||||
|
self: *const VTEvent,
|
||||||
|
filter: *cimgui.c.ImGuiTextFilter,
|
||||||
|
) bool {
|
||||||
|
return cimgui.c.ImGuiTextFilter_PassFilter(filter, self.str.ptr, null);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Our VT stream handler.
|
/// Our VT stream handler.
|
||||||
const Handler = struct {
|
pub const VTHandler = struct {
|
||||||
/// The surface that the inspector is attached to. We use this instead
|
/// The surface that the inspector is attached to. We use this instead
|
||||||
/// of the inspector because this is pointer-stable.
|
/// of the inspector because this is pointer-stable.
|
||||||
surface: *Surface,
|
surface: *Surface,
|
||||||
|
|
||||||
/// Exclude certain actions by tag.
|
/// Exclude certain actions by tag.
|
||||||
filter_exclude: ActionTagSet = ActionTagSet.initMany(&.{.print}),
|
filter_exclude: ActionTagSet = ActionTagSet.initMany(&.{.print}),
|
||||||
|
filter_text: *cimgui.c.ImGuiTextFilter,
|
||||||
|
|
||||||
const ActionTagSet = std.EnumSet(terminal.Parser.Action.Tag);
|
const ActionTagSet = std.EnumSet(terminal.Parser.Action.Tag);
|
||||||
|
|
||||||
|
pub fn init(surface: *Surface) VTHandler {
|
||||||
|
return .{
|
||||||
|
.surface = surface,
|
||||||
|
.filter_text = cimgui.c.ImGuiTextFilter_ImGuiTextFilter(""),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *VTHandler) void {
|
||||||
|
cimgui.c.ImGuiTextFilter_destroy(self.filter_text);
|
||||||
|
}
|
||||||
|
|
||||||
/// This is called with every single terminal action.
|
/// This is called with every single terminal action.
|
||||||
pub fn handleManually(self: *Handler, action: terminal.Parser.Action) !bool {
|
pub fn handleManually(self: *VTHandler, action: terminal.Parser.Action) !bool {
|
||||||
const insp = self.surface.inspector orelse return false;
|
const insp = self.surface.inspector orelse return false;
|
||||||
|
|
||||||
// We ignore certain action types that are too noisy.
|
// We ignore certain action types that are too noisy.
|
||||||
@ -76,8 +97,16 @@ const Handler = struct {
|
|||||||
// We return true because we did "handle" it by ignoring it.
|
// We return true because we did "handle" it by ignoring it.
|
||||||
if (self.filter_exclude.contains(std.meta.activeTag(action))) return true;
|
if (self.filter_exclude.contains(std.meta.activeTag(action))) return true;
|
||||||
|
|
||||||
|
// Build our event
|
||||||
const alloc = self.surface.alloc;
|
const alloc = self.surface.alloc;
|
||||||
const ev = try VTEvent.init(alloc, action);
|
var ev = try VTEvent.init(alloc, action);
|
||||||
|
errdefer ev.deinit(alloc);
|
||||||
|
|
||||||
|
// Check if the event passes the filter
|
||||||
|
if (!ev.passFilter(self.filter_text)) {
|
||||||
|
ev.deinit(alloc);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const max_capacity = 100;
|
const max_capacity = 100;
|
||||||
insp.vt_events.append(ev) catch |err| switch (err) {
|
insp.vt_events.append(ev) catch |err| switch (err) {
|
||||||
|
Reference in New Issue
Block a user