'plonk' => [ '--threads|--from=IDENT',
'exclude mail matching From: or threads from non-Message-ID searches',
qw(stdin| threads|t from|f=s mid=s oid=s), @c_opt ],
-'mark' => [ 'MESSAGE_FLAGS...',
- 'set/unset keywords on message(s) from stdin',
- qw(stdin| oid=s exact by-mid|mid:s), @c_opt ],
+'mark' => [ 'KEYWORDS...',
+ 'set/unset keywords on message(s)',
+ qw(stdin| in-format|F=s input|i=s@ oid=s@ mid=s@), @c_opt,
+ pass_through('-kw:foo for delete') ],
'forget' => [ '[--stdin|--oid=OID|--by-mid=MID]',
"exclude message(s) on stdin from `q' search results",
qw(stdin| oid=s exact by-mid|mid:s), @c_opt ],
'leistore.dir' => 'top-level storage location',
);
-my @WQ_KEYS = qw(lxs l2m imp mrr cnv p2q); # internal workers
+my @WQ_KEYS = qw(lxs l2m imp mrr cnv p2q mark); # internal workers
# pronounced "exit": x_it(1 << 8) => exit(1); x_it(13) => SIGPIPE
sub x_it ($$) {
x_it($self, 13);
}
-sub lei_atfork_child {
+sub _lei_atfork_child {
my ($self, $persist) = @_;
# we need to explicitly close things which are on stack
if ($persist) {
open STDERR, '+>&='.fileno($self->{2}) or warn "open $!";
delete $self->{0};
}
- delete @$self{qw(cnv)};
+ delete @$self{qw(cnv mark imp)};
for (delete @$self{qw(3 old_1 au_done)}) {
close($_) if defined($_);
}
sub workers_start {
my ($lei, $wq, $ident, $jobs, $ops) = @_;
$ops = {
- '!' => [ $lei->can('fail_handler'), $lei ],
- '|' => [ $lei->can('sigpipe_handler'), $lei ],
- 'x_it' => [ $lei->can('x_it'), $lei ],
- 'child_error' => [ $lei->can('child_error'), $lei ],
- %$ops
+ '!' => [ \&fail_handler, $lei ],
+ '|' => [ \&sigpipe_handler, $lei ],
+ 'x_it' => [ \&x_it, $lei ],
+ 'child_error' => [ \&child_error, $lei ],
+ ($ops ? %$ops : ()),
};
+ $ops->{''} //= [ \&dclose, $lei ];
require PublicInbox::PktOp;
($lei->{pkt_op_c}, $lei->{pkt_op_p}) = PublicInbox::PktOp->pair($ops);
$wq->wq_workers_start($ident, $jobs, $lei->oldset, { lei => $lei });
}
}
+sub lazy_cb ($$$) {
+ my ($self, $cmd, $pfx) = @_;
+ my $ucmd = $cmd;
+ $ucmd =~ tr/-/_/;
+ my $cb;
+ $cb = $self->can($pfx.$ucmd) and return $cb;
+ my $base = $ucmd;
+ $base =~ s/_([a-z])/\u$1/g;
+ my $pkg = "PublicInbox::Lei\u$base";
+ ($INC{"PublicInbox/Lei\u$base.pm"} // eval("require $pkg")) ?
+ $pkg->can($pfx.$ucmd) : undef;
+}
+
sub dispatch {
my ($self, $cmd, @argv) = @_;
local $current_lei = $self; # for __WARN__
push @{$self->{opt}->{substr($cmd, 1, 1)}}, $v;
$cmd = shift(@argv) // return _help($self, 'no command given');
}
- my $func = "lei_$cmd";
- $func =~ tr/-/_/;
- my $cb = __PACKAGE__->can($func) // ($CMD{$cmd} ? do {
- my $mod = "PublicInbox::Lei\u$cmd";
- ($INC{"PublicInbox/Lei\u$cmd.pm"} //
- eval("require $mod")) ? $mod->can($func) : undef;
- } : undef);
- if ($cb) {
+ if (my $cb = lazy_cb(__PACKAGE__, $cmd, 'lei_')) {
optparse($self, $cmd, \@argv) or return;
$self->{opt}->{c} and (_tmp_cfg($self) // return);
if (my $chdir = $self->{opt}->{C}) {
my ($self, @argv) = @_;
}
-sub lei_mark {
- my ($self, @argv) = @_;
-}
-
sub _config {
my ($self, @argv) = @_;
my %env = (%{$self->{env}}, GIT_CONFIG => undef);
@v;
} grep(/\A(?:[\w-]+\|)*$opt\b.*?(?:\t$cmd)?\z/, keys %OPTDESC);
}
- $cmd =~ tr/-/_/;
- if (my $sub = $self->can("_complete_$cmd")) {
- puts $self, $sub->($self, @argv, $cur ? ($cur) : ());
+ if (my $cb = lazy_cb($self, $cmd, '_complete_')) {
+ puts $self, $cb->($self, @argv, $cur ? ($cur) : ());
}
# TODO: URLs, pathnames, OIDs, MIDs, etc... See optparse() for
# proto parsing.