"lei export-kw" no longer completes for anonymous sources.
More commands use "lei refresh-mail-sync" as a basis for their
completion work, as well.
";AUTH=ANONYMOUS@" is stripped from completions since it was
preventing bash completion from working on AUTH=ANONYMOUS IMAP
URLs. I'm not sure if there's a better way, but all of our code
works fine without specifying AUTH=ANONYMOUS as a command-line
arg.
Finally, we fallback to using more candidates if none can
be found, allowing multiple URLs to be completed.
sub _complete_export_kw {
my ($lei, @argv) = @_;
- my $lms = $lei->lms or return;
+ my $lms = $lei->lms or return ();
my $match_cb = $lei->complete_url_prepare(\@argv);
- map { $match_cb->($_) } $lms->folders;
+ # filter-out read-only sources:
+ my @k = grep(!m!(?://;AUTH=ANONYMOUS\@|\A(?:nntps?|s?news)://)!,
+ $lms->folders($argv[-1], 1));
+ my @m = map { $match_cb->($_) } @k;
+ @m ? @m : @k;
}
no warnings 'once';
$re = quotemeta($re);
}
my $match_cb = sub {
+ # the "//;" here (for AUTH=ANONYMOUS) interacts badly with
+ # bash tab completion, strip it out for now since our commands
+ # work w/o it. Not sure if there's a better solution...
+ $_[0] =~ s!//;AUTH=ANONYMOUS\@!//!i;
+ $_[0] =~ s!;!\\;!g;
# only return the part specified on the CLI
# don't duplicate if already 100% completed
$_[0] =~ /\A$re(\Q$cur\E.*)/ ? ($cur eq $1 ? () : $1) : ()
package PublicInbox::LeiForgetMailSync;
use strict;
use v5.10.1;
-use PublicInbox::LeiExportKw;
+use PublicInbox::LeiRefreshMailSync;
sub lei_forget_mail_sync {
my ($lei, @folders) = @_;
$lms->forget_folders(@folders);
}
-*_complete_forget_mail_sync = \&PublicInbox::LeiExportKw::_complete_export_kw;
+*_complete_forget_mail_sync =
+ \&PublicInbox::LeiRefreshMailSync::_complete_refresh_mail_sync;
1;
sub _complete_import {
my ($lei, @argv) = @_;
- my $match_cb = $lei->complete_url_prepare(\@argv);
- my @m = map { $match_cb->($_) } $lei->url_folder_cache->keys;
- my %f = map { $_ => 1 } @m;
+ my ($re, $cur, $match_cb) = $lei->complete_url_prepare(\@argv);
+ my @k = $lei->url_folder_cache->keys($argv[-1], 1);
+ my @m = map { $match_cb->($_) } @k;
+ my %f = map { $_ => 1 } (@m ? @m : @k);
if (my $lms = $lei->lms) {
- @m = map { $match_cb->($_) } $lms->folders;
- @f{@m} = @m;
+ @k = $lms->folders($argv[-1], 1);
+ @m = map { $match_cb->($_) } @k;
+ if (@m) { @f{@m} = @m } else { @f{@k} = @k }
}
keys %f;
}
}
sub _complete_inspect {
- my ($lei, @argv) = @_;
- my $lms = $lei->lms or return;
- my $match_cb = $lei->complete_url_prepare(\@argv);
- map { $match_cb->($_) } $lms->folders;
+ require PublicInbox::LeiRefreshMailSync;
+ PublicInbox::LeiRefreshMailSync::_complete_refresh_mail_sync(@_);
+ # TODO: message-ids?, blobs? could get expensive...
}
1;
}
sub _complete_lcat {
- my ($lei, @argv) = @_;
- my $lms = $lei->lms or return;
- my $match_cb = $lei->complete_url_prepare(\@argv);
- map { $match_cb->($_) } $lms->folders;
+ require PublicInbox::LeiRefreshMailSync;
+ PublicInbox::LeiRefreshMailSync::_complete_refresh_mail_sync(@_);
+ # TODO: message-ids?, blobs? could get expensive...
}
1;
sub _complete_ls_mail_source {
my ($lei, @argv) = @_;
my $match_cb = $lei->complete_url_prepare(\@argv);
- my @m = map { $match_cb->($_) } $lei->url_folder_cache->keys;
- my %f = map { $_ => 1 } @m;
+ my @k = $lei->url_folder_cache->keys($argv[-1], 1);
+ my @m = map { $match_cb->($_) } @k;
+ my %f = map { $_ => 1 } (@m ? @m : @k);
if (my $lms = $lei->lms) {
- @m = map { $match_cb->($_) } grep(
- m!\A(?:imaps?|nntps?|s?news)://!, $lms->folders);
- @f{@m} = @m;
+ @k = $lms->folders($argv[-1], 1);
+ @m = map { $match_cb->($_) } grep(m!\A[a-z]+://!, @k);
+ if (@m) { @f{@m} = @m } else { @f{@k} = @k }
}
keys %f;
}
# returns a list of folders used for completion
sub folders {
- my ($self, $pfx) = @_;
- my $dbh = $self->{dbh} //= dbh_new($self);
+ my ($self, @pfx) = @_;
my $sql = 'SELECT loc FROM folders';
- my @pfx;
- if (defined $pfx) {
+ if (defined($pfx[0])) {
$sql .= ' WHERE loc LIKE ? ESCAPE ?';
- @pfx = ($pfx, '\\');
+ my $anywhere = !!$pfx[1];
+ $pfx[1] = '\\';
$pfx[0] =~ s/([%_\\])/\\$1/g; # glob chars
$pfx[0] .= '%';
+ substr($pfx[0], 0, 0, '%') if $anywhere;
+ } else {
+ @pfx = (); # [0] may've been undef
}
+ my $dbh = $self->{dbh} //= dbh_new($self);
map { $_->[0] } @{$dbh->selectall_arrayref($sql, undef, @pfx)};
}
use strict;
use v5.10.1;
use parent qw(PublicInbox::IPC PublicInbox::LeiInput);
-use PublicInbox::LeiExportKw;
+use PublicInbox::LeiImport;
use PublicInbox::InboxWritable qw(eml_from_path);
use PublicInbox::Import;
undef;
}
+sub _complete_refresh_mail_sync {
+ my ($lei, @argv) = @_;
+ my $lms = $lei->lms or return ();
+ my $match_cb = $lei->complete_url_prepare(\@argv);
+ my @k = $lms->folders($argv[-1], 1);
+ my @m = map { $match_cb->($_) } @k;
+ @m ? @m : @k
+}
+
no warnings 'once';
-*_complete_refresh_mail_sync = \&PublicInbox::LeiExportKw::_complete_export_kw;
*net_merge_all_done = \&PublicInbox::LeiInput::input_only_net_merge_all_done;
1;
# Workaround bash word-splitting s to ['kw', ':', 'keyword' ...]
# Maybe there's a better way to go about this in
# contrib/completion/lei-completion.bash
-sub _complete_mark_common ($) {
+sub _complete_tag_common ($) {
my ($argv) = @_;
# Workaround bash word-splitting URLs to ['https', ':', '//' ...]
# Maybe there's a better way to go about this in
# FIXME: same problems as _complete_forget_external and similar
sub _complete_tag {
my ($self, @argv) = @_;
+ require PublicInbox::LeiImport;
+ my @in = PublicInbox::LeiImport::_complete_import(@_);
my @L = eval { $self->_lei_store->search->all_terms('L') };
- my @all = ((map { ("+kw:$_", "-kw:$_") } @PublicInbox::LeiInput::KW),
+ my @kwL = ((map { ("+kw:$_", "-kw:$_") } @PublicInbox::LeiInput::KW),
(map { ("+L:$_", "-L:$_") } @L));
- return @all if !@argv;
- my ($cur, $re) = _complete_mark_common(\@argv);
- map {
+ my ($cur, $re) = _complete_tag_common(\@argv);
+ my @m = map {
# only return the part specified on the CLI
# don't duplicate if already 100% completed
/\A$re(\Q$cur\E.*)/ ? ($cur eq $1 ? () : $1) : ();
- } grep(/$re\Q$cur/, @all);
+ } grep(/$re\Q$cur/, @kwL);
+ (@in, (@m ? @m : @kwL));
}
no warnings 'once'; # the following works even when LeiAuth is lazy-loaded
}
sub keys {
- my ($self) = @_;
- my $sth = $self->dbh->prepare_cached(<<'', undef, 1);
-SELECT k FROM kv
-
- $sth->execute;
- map { $_->[0] } @{$sth->fetchall_arrayref};
+ my ($self, @pfx) = @_;
+ my $sql = 'SELECT k FROM kv';
+ if (defined $pfx[0]) {
+ $sql .= ' WHERE k LIKE ? ESCAPE ?';
+ my $anywhere = !!$pfx[1];
+ $pfx[1] = '\\';
+ $pfx[0] =~ s/([%_\\])/\\$1/g; # glob chars
+ $pfx[0] .= '%';
+ substr($pfx[0], 0, 0, '%') if $anywhere;
+ } else {
+ @pfx = (); # [0] may've been undef
+ }
+ map { $_->[0] } @{$self->dbh->selectall_arrayref($sql, undef, @pfx)};
}
sub delete_by_val {