Nothing major, just some things to make lcat nicer for the inevitable network outages to come Eric Wong (4): lei lcat+inspect: start wiring up completion lei lcat: allow IMAP folder URLs w/o UIDVALIDITY lei lcat: support maildir:... paths, too lei: support implicit stdin by default lib/PublicInbox/LEI.pm | 12 ++++++++++-- lib/PublicInbox/LeiInspect.pm | 8 ++++++++ lib/PublicInbox/LeiLcat.pm | 33 ++++++++++++++++++++++++++++++--- lib/PublicInbox/LeiRediff.pm | 1 - lib/PublicInbox/LeiRm.pm | 1 - t/lei-import-imap.t | 3 +++ t/lei-p2q.t | 4 ++++ 7 files changed, 55 insertions(+), 7 deletions(-)
Colons and other delimiters still cause problems for our bash completion, but some completion is better than no completion. --- lib/PublicInbox/LeiInspect.pm | 8 ++++++++ lib/PublicInbox/LeiLcat.pm | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/lib/PublicInbox/LeiInspect.pm b/lib/PublicInbox/LeiInspect.pm index 7205979e..eb2634b4 100644 --- a/lib/PublicInbox/LeiInspect.pm +++ b/lib/PublicInbox/LeiInspect.pm @@ -99,4 +99,12 @@ sub lei_inspect { $lei->out(']') if $multi; } +sub _complete_inspect { + my ($lei, @argv) = @_; + my $sto = $lei->_lei_store or return; + my $lms = $sto->search->lms or return; + my $match_cb = $lei->complete_url_prepare(\@argv); + map { $match_cb->($_) } $lms->folders; +} + 1; diff --git a/lib/PublicInbox/LeiLcat.pm b/lib/PublicInbox/LeiLcat.pm index effc3682..81ab1e36 100644 --- a/lib/PublicInbox/LeiLcat.pm +++ b/lib/PublicInbox/LeiLcat.pm @@ -132,4 +132,12 @@ no args allowed on command-line with --stdin $lei->_start_query; } +sub _complete_lcat { + my ($lei, @argv) = @_; + my $sto = $lei->_lei_store or return; + my $lms = $sto->search->lms or return; + my $match_cb = $lei->complete_url_prepare(\@argv); + grep(m!\A[a-z]+://!, map { $match_cb->($_) } $lms->folders); +} + 1;
Requiring UIDVALIDITY on the command-line is of course unreasonable. --- lib/PublicInbox/LeiLcat.pm | 12 +++++++++++- t/lei-import-imap.t | 3 +++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/PublicInbox/LeiLcat.pm b/lib/PublicInbox/LeiLcat.pm index 81ab1e36..5bd20c1f 100644 --- a/lib/PublicInbox/LeiLcat.pm +++ b/lib/PublicInbox/LeiLcat.pm @@ -24,7 +24,17 @@ sub lcat_imap_uri ($$) { } elsif (defined(my $fid = $lms->fid_for($$uri))) { push @{$lei->{lcat_fid}}, $fid; } else { - $lei->child_error(1 << 8, "# unknown folder: $uri"); + my $folders = [ $$uri ]; + my $err = $lms->arg2folder($lei, $folders); + $lei->qerr(@{$err->{qerr}}) if $err && $err->{qerr}; + if ($err && $err->{fail}) { + $lei->child_error(1 << 8, "# unknown folder: $uri"); + } else { + for my $f (@$folders) { + my $fid = $lms->fid_for($f); + push @{$lei->{lcat_fid}}, $fid; + } + } } } diff --git a/t/lei-import-imap.t b/t/lei-import-imap.t index 895b19ff..34fd6cf9 100644 --- a/t/lei-import-imap.t +++ b/t/lei-import-imap.t @@ -13,6 +13,7 @@ my $host_port = tcp_host_port($sock); undef $sock; test_lei({ tmpdir => $tmpdir }, sub { my $url = "imap://$host_port/t.v2.0"; + my $url_orig = $url; lei_ok(qw(q z:1..)); my $out = json_utf8->decode($lei_out); @@ -100,6 +101,8 @@ test_lei({ tmpdir => $tmpdir }, sub { lei_ok qw(lcat -f json), $uid_url; $out = json_utf8->decode($lei_out); is(scalar(@$out), 2, 'got JSON') or diag explain($out); + lei_ok qw(lcat), $url_orig; + is($lei_out, $orig, 'lcat w/o UID works'); }); done_testing;
This could be helpful in case when a Maildir is on a slow or unmounted filesystem and lei/store is on fast storage. --- lib/PublicInbox/LeiLcat.pm | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/lib/PublicInbox/LeiLcat.pm b/lib/PublicInbox/LeiLcat.pm index 5bd20c1f..cb5eb5b4 100644 --- a/lib/PublicInbox/LeiLcat.pm +++ b/lib/PublicInbox/LeiLcat.pm @@ -11,10 +11,26 @@ use PublicInbox::LeiViewText; use URI::Escape qw(uri_unescape); use PublicInbox::MID qw($MID_EXTRACT); +sub lcat_folder ($$$) { + my ($lei, $lms, $folder) = @_; + $lms //= $lei->{lse}->lms // return; + my $folders = [ $folder]; + my $err = $lms->arg2folder($lei, $folders); + $lei->qerr(@{$err->{qerr}}) if $err && $err->{qerr}; + if ($err && $err->{fail}) { + $lei->child_error(1 << 8, "# unknown folder: $folder"); + } else { + for my $f (@$folders) { + my $fid = $lms->fid_for($f); + push @{$lei->{lcat_fid}}, $fid; + } + } +} + sub lcat_imap_uri ($$) { my ($lei, $uri) = @_; my $lms = $lei->{lse}->lms or return; - # cf. LeiToMail->wq_atexit_child + # cf. LeiXsearch->lcat_dump if (defined $uri->uid) { my $oidhex = $lms->imap_oid($lei, $uri); if (ref(my $err = $oidhex)) { # art2folder error @@ -24,17 +40,7 @@ sub lcat_imap_uri ($$) { } elsif (defined(my $fid = $lms->fid_for($$uri))) { push @{$lei->{lcat_fid}}, $fid; } else { - my $folders = [ $$uri ]; - my $err = $lms->arg2folder($lei, $folders); - $lei->qerr(@{$err->{qerr}}) if $err && $err->{qerr}; - if ($err && $err->{fail}) { - $lei->child_error(1 << 8, "# unknown folder: $uri"); - } else { - for my $f (@$folders) { - my $fid = $lms->fid_for($f); - push @{$lei->{lcat_fid}}, $fid; - } - } + lcat_folder($lei, $lms, $$uri); } } @@ -44,7 +50,10 @@ sub extract_1 ($$) { my $u = $1; require PublicInbox::URIimap; lcat_imap_uri($lei, PublicInbox::URIimap->new($u)); - '""'; # blank query, using {lcat_blob} or {lcat + '""'; # blank query, using {lcat_blob} or {lcat_fid} + } elsif ($x =~ m!\b(maildir:.+)!i) { + lcat_folder($lei, undef, $1); + '""'; # blank query, using {lcat_blob} or {lcat_fid} } elsif ($x =~ m!\b([a-z]+?://\S+)!i) { my $u = $1; $u =~ s/[\>\]\)\,\.\;]+\z//; @@ -147,7 +156,7 @@ sub _complete_lcat { my $sto = $lei->_lei_store or return; my $lms = $sto->search->lms or return; my $match_cb = $lei->complete_url_prepare(\@argv); - grep(m!\A[a-z]+://!, map { $match_cb->($_) } $lms->folders); + map { $match_cb->($_) } $lms->folders; } 1;
This adds implicit stdin suppport for p2q and lcat, while rm and rediff no longer need explicit support for it. --- lib/PublicInbox/LEI.pm | 12 ++++++++++-- lib/PublicInbox/LeiRediff.pm | 1 - lib/PublicInbox/LeiRm.pm | 1 - t/lei-p2q.t | 4 ++++ 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm index f2dfc320..3527cf09 100644 --- a/lib/PublicInbox/LEI.pm +++ b/lib/PublicInbox/LEI.pm @@ -638,7 +638,15 @@ sub optparse ($$$) { my $ok; for my $o (@or) { if ($o =~ /\A--([a-z0-9\-]+)/) { - $ok = defined($OPT->{$1}); + my $sw = $1; + # assume pipe/regular file on stdin + # w/o args means stdin + if ($sw eq 'stdin' && !@$argv && + (-p $self->{0} || + -f _) && -r _) { + $OPT->{stdin} //= 1; + } + $ok = defined($OPT->{$sw}); last if $ok; } elsif (defined($argv->[$i])) { $ok = 1; @@ -906,7 +914,7 @@ sub start_mua { } push @cmd, $mfolder unless defined($replaced); if ($self->{sock}) { # lei(1) client process runs it - # restore terminal: echo $query | lei q -stdin --mua=... + # restore terminal: echo $query | lei q --stdin --mua=... my $io = []; $io->[0] = $self->{1} if $self->{opt}->{stdin} && -t $self->{1}; send_exec_cmd($self, $io, \@cmd, {}); diff --git a/lib/PublicInbox/LeiRediff.pm b/lib/PublicInbox/LeiRediff.pm index 2e793df5..c8bd0dfb 100644 --- a/lib/PublicInbox/LeiRediff.pm +++ b/lib/PublicInbox/LeiRediff.pm @@ -201,7 +201,6 @@ sub input_eml_cb { # callback for all emails sub lei_rediff { my ($lei, @inputs) = @_; $lei->_lei_store(1)->write_prepare($lei); - $lei->{opt}->{stdin} = 1 if !@inputs; $lei->{opt}->{'in-format'} //= 'eml'; # maybe it's a non-email (code) blob from a coderepo my $git_dirs = $lei->{opt}->{'git-dir'} //= []; diff --git a/lib/PublicInbox/LeiRm.pm b/lib/PublicInbox/LeiRm.pm index 185b6a15..c6d28045 100644 --- a/lib/PublicInbox/LeiRm.pm +++ b/lib/PublicInbox/LeiRm.pm @@ -31,7 +31,6 @@ sub input_maildir_cb { sub lei_rm { my ($lei, @inputs) = @_; $lei->_lei_store(1)->write_prepare($lei); - $lei->{opt}->{stdin} = 1 if !@inputs; $lei->{opt}->{'in-format'} //= 'eml'; my $self = bless { -wq_nr_workers => 1 }, __PACKAGE__; $self->prepare_inputs($lei, \@inputs) or return; diff --git a/t/lei-p2q.t b/t/lei-p2q.t index f8b073cf..58506f94 100644 --- a/t/lei-p2q.t +++ b/t/lei-p2q.t @@ -14,6 +14,10 @@ test_lei(sub { lei_ok([qw(p2q -w dfpost -)], undef, { %$lei_opt, 0 => $fh }); is($lei_out, "dfpost:6e006fd73b1d\n", '--stdin') or diag $lei_err; + sysseek($fh, 0, 0) or xbail "lseek: $!"; + lei_ok([qw(p2q -w dfpost)], undef, { %$lei_opt, 0 => $fh }); + is($lei_out, "dfpost:6e006fd73b1d\n", 'implicit --stdin'); + lei_ok(qw(p2q --uri t/data/0001.patch -w), 'dfpost,dfn'); is($lei_out, "dfpost%3A6e006fd73b1d+". "dfn%3Alib%2FPublicInbox%2FSearch.pm\n",
Eric Wong <e@80x24.org> wrote:
> Nothing major, just some things to make lcat nicer for the
> inevitable network outages to come
>
> Eric Wong (4):
> lei lcat+inspect: start wiring up completion
> lei lcat: allow IMAP folder URLs w/o UIDVALIDITY
Btw, "lei lcat $URL" is great in the case adding a label/keyword
with "lei import" was forgotten:
lei import $URL
# oops, I forgot to add +L:somelabel to the above import
# invocation
lei lcat $URL -f mboxrd | lei tag -f mboxrd - +L:somelabel
Running "lei tag $URL +L:somelabel" directly works, too,
but that's extra network traffic + latency.