From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-Status: No, score=-4.0 required=3.0 tests=ALL_TRUSTED,BAYES_00 shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id EC98C1FA12 for ; Tue, 5 Jan 2021 09:04:37 +0000 (UTC) From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 2/4] lei: automatic pager support Date: Tue, 5 Jan 2021 09:04:35 +0000 Message-Id: <20210105090437.22801-3-e@80x24.org> In-Reply-To: <20210105090437.22801-1-e@80x24.org> References: <20210105090437.22801-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: Just like git, we'll start a pager when outputting to a terminal for user-friendliness when reading many messages. --- lib/PublicInbox/LEI.pm | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm index 9a3b1ee3..6073a713 100644 --- a/lib/PublicInbox/LEI.pm +++ b/lib/PublicInbox/LEI.pm @@ -19,7 +19,7 @@ use PublicInbox::Config; use PublicInbox::Syscall qw(SFD_NONBLOCK EPOLLIN EPOLLONESHOT); use PublicInbox::Sigfd; use PublicInbox::DS qw(now dwaitpid); -use PublicInbox::Spawn qw(spawn run_die); +use PublicInbox::Spawn qw(spawn run_die popen_rd); use PublicInbox::OnDestroy; use Text::Wrap qw(wrap); use File::Path qw(mkpath); @@ -619,6 +619,26 @@ sub lei_git { # support passing through random git commands dwaitpid($pid, \&reap_exec, $self); } +# caller needs to "-t $self->{1}" to check if tty +sub start_pager { + my ($self) = @_; + my $env = $self->{env}; + my $fh = popen_rd([qw(git var GIT_PAGER)], $env); + chomp(my $pager = <$fh> // ''); + close($fh) or warn "`git var PAGER' error: \$?=$?"; + return if $pager eq 'cat' || $pager eq ''; + $env->{LESS} //= 'FRX'; + $env->{LV} //= '-c'; + $env->{COLUMNS} //= 80; # TODO TIOCGWINSZ + $env->{MORE} //= 'FRX' if $^O eq 'freebsd'; + pipe(my ($r, $w)) or return warn "pipe: $!"; + my $rdr = { 0 => $r, 1 => $self->{1}, 2 => $self->{2} }; + $self->{1} = $w; + $self->{2} = $w if -t $self->{2}; + $self->{'pager.pid'} = spawn([$pager], $env, $rdr); + $env->{GIT_PAGER_IN_USE} = 'true'; # we may spawn git +} + sub accept_dispatch { # Listener {post_accept} callback my ($sock) = @_; # ignore other $sock->blocking(1); @@ -794,6 +814,12 @@ sub oneshot { # ensures stdout hits the FS before sock disconnects so a client # can immediately reread it -sub DESTROY { $_[0]->{1}->autoflush(1) } +sub DESTROY { + my ($self) = @_; + $self->{1}->autoflush(1); + if (my $pid = delete $self->{'pager.pid'}) { + dwaitpid($pid, undef, $self->{sock}); + } +} 1;