From 60dd55423fae29d664b6037343da7f098098c351 Mon Sep 17 00:00:00 2001 From: Nathan Craddock Date: Thu, 27 Jul 2023 18:54:38 -0600 Subject: [PATCH] fix: optimize preview spawning Don't show a preview when there are no lines selected, and don't respawn a preview if the same line is selected between redraws. --- src/Previewer.zig | 16 ++++++++++++++-- src/ui.zig | 8 ++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/Previewer.zig b/src/Previewer.zig index 167fece..8e36f03 100644 --- a/src/Previewer.zig +++ b/src/Previewer.zig @@ -1,5 +1,6 @@ //! Manages child processes used for previewing information about the selected line +const mem = std.mem; const process = std.process; const std = @import("std"); @@ -16,6 +17,8 @@ loop: *Loop, shell: []const u8, cmd_parts: [2][]const u8, +current_arg: []const u8 = "", + child: ?Child = null, stdout: ArrayList(u8), stderr: ArrayList(u8), @@ -42,12 +45,21 @@ pub fn init(allocator: Allocator, loop: *Loop, cmd: []const u8, arg: []const u8) return previewer; } -pub fn spawn(previewer: *Previewer, arg: []const u8) !void { +pub fn reset(previewer: *Previewer) !void { previewer.stdout.clearRetainingCapacity(); previewer.stderr.clearRetainingCapacity(); if (previewer.child) |*child| { _ = try child.kill(); } +} + +pub fn spawn(previewer: *Previewer, arg: []const u8) !void { + // If the arg is already being previewed we don't need to do any work + if (mem.eql(u8, arg, previewer.current_arg)) { + return; + } + + try previewer.reset(); const command = try std.fmt.allocPrint(previewer.allocator, "{s}{s}{s} | expand -t4", .{ previewer.cmd_parts[0], arg, previewer.cmd_parts[1] }); @@ -58,8 +70,8 @@ pub fn spawn(previewer: *Previewer, arg: []const u8) !void { try child.spawn(); previewer.loop.setChild(child.stdout.?.handle, child.stderr.?.handle); - previewer.child = child; + previewer.current_arg = try previewer.allocator.dupe(u8, arg); } pub fn read(previewer: *Previewer, stream: enum { stdout, stderr }) !void { diff --git a/src/ui.zig b/src/ui.zig index 856cab2..65edd17 100644 --- a/src/ui.zig +++ b/src/ui.zig @@ -424,12 +424,12 @@ pub fn run( } // The selection changed and the child process should be respawned - if (state.selection_changed and state.preview != null) { + if (state.selection_changed) if (state.preview) |*preview| { state.selection_changed = false; if (filtered.len > 0) { - try state.preview.?.spawn(filtered[state.selected + state.offset].str); - } - } + try preview.spawn(filtered[state.selected + state.offset].str); + } else try preview.reset(); + }; if (state.redraw) { state.redraw = false;