diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/PublicInbox/LeiExternal.pm | 31 | ||||
-rw-r--r-- | lib/PublicInbox/LeiForgetExternal.pm | 8 | ||||
-rw-r--r-- | lib/PublicInbox/LeiImport.pm | 22 | ||||
-rw-r--r-- | lib/PublicInbox/LeiQuery.pm | 2 |
4 files changed, 31 insertions, 32 deletions
diff --git a/lib/PublicInbox/LeiExternal.pm b/lib/PublicInbox/LeiExternal.pm index 3e2a2288..31b9bd1e 100644 --- a/lib/PublicInbox/LeiExternal.pm +++ b/lib/PublicInbox/LeiExternal.pm @@ -86,39 +86,34 @@ sub canonicalize_excludes { # returns an anonymous sub which returns an array of potential results sub complete_url_prepare { my $argv = $_[-1]; # $_[0] may be $lei - # Workaround bash word-splitting URLs to ['https', ':', '//' ...] - # Maybe there's a better way to go about this in - # contrib/completion/lei-completion.bash - my $re = ''; - my $cur = pop(@$argv) // ''; + # Workaround bash default COMP_WORDBREAKS splitting URLs to + # ['https', ':', '//', ...]. COMP_WORDBREAKS is global for all + # completions loaded, not just ours, so we can't change it. + # cf. contrib/completion/lei-completion.bash + my ($pfx, $cur) = ('', pop(@$argv) // ''); if (@$argv) { my @x = @$argv; - if ($cur eq ':' && @x) { + if ($cur =~ /\A[:;=]\z/) { # COMP_WORDBREAKS + URL union push @x, $cur; $cur = ''; } - while (@x > 2 && $x[0] !~ /\A(?:http|nntp|imap)s?\z/i && - $x[1] ne ':') { - shift @x; + while (@x && $pfx !~ m!\A(?: (?:[\+\-]?(?:L|kw):) | + (?:(?:imap|nntp|http)s?:) | + (?:--\w?\z)|(?:-\w?\z) )!x) { + $pfx = pop(@x).$pfx; } - if (@x >= 2) { # qw(https : hostname : 443) or qw(http :) - $re = join('', @x); - } else { # just filter out the flags and hope for the best - $re = join('', grep(!/^-/, @$argv)); - } - $re = quotemeta($re); } + my $re = qr!\A\Q$pfx\E(\Q$cur\E.*)!; 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) : () + $_[0] =~ $re ? ($cur eq $1 ? () : $1) : () }; - wantarray ? ($re, $cur, $match_cb) : $match_cb; + wantarray ? ($pfx, $cur, $match_cb) : $match_cb; } 1; diff --git a/lib/PublicInbox/LeiForgetExternal.pm b/lib/PublicInbox/LeiForgetExternal.pm index 07f0ac80..39bfc60b 100644 --- a/lib/PublicInbox/LeiForgetExternal.pm +++ b/lib/PublicInbox/LeiForgetExternal.pm @@ -32,14 +32,10 @@ sub lei_forget_external { sub _complete_forget_external { my ($lei, @argv) = @_; my $cfg = $lei->_lei_cfg or return (); - my ($cur, $re, $match_cb) = $lei->complete_url_prepare(\@argv); - # FIXME: bash completion off "http:" or "https:" when the last - # character is a colon doesn't work properly even if we're - # returning "//$HTTP_HOST/$PATH_INFO/", not sure why, could - # be a bash issue. + my ($pfx, $cur, $match_cb) = $lei->complete_url_prepare(\@argv); map { $match_cb->(substr($_, length('external.'))); - } grep(/\Aexternal\.$re\Q$cur/, @{$cfg->{-section_order}}); + } grep(/\Aexternal\.\Q$pfx$cur/, @{$cfg->{-section_order}}); } 1; diff --git a/lib/PublicInbox/LeiImport.pm b/lib/PublicInbox/LeiImport.pm index 2d91e4c4..9053048a 100644 --- a/lib/PublicInbox/LeiImport.pm +++ b/lib/PublicInbox/LeiImport.pm @@ -115,18 +115,24 @@ sub lei_import { # the main "lei import" method sub _complete_import { my ($lei, @argv) = @_; - my ($re, $cur, $match_cb) = $lei->complete_url_prepare(\@argv); - my @k = $lei->url_folder_cache->keys($argv[-1] // undef, 1); + my $has_arg = @argv; + my ($pfx, $cur, $match_cb) = $lei->complete_url_prepare(\@argv); + my @try = $has_arg ? ($pfx.$cur, $argv[-1]) : ($argv[-1]); + push(@try, undef) if defined $try[-1]; + my (@f, @k); + for (@try) { + @k = $lei->url_folder_cache->keys($_, 1) and last; + } my @L = eval { $lei->_lei_store->search->all_terms('L') }; push(@k, map { "+L:$_" } @L); - my @m = map { $match_cb->($_) } @k; - my %f = map { $_ => 1 } (@m ? @m : @k); if (my $lms = $lei->lms) { - @k = $lms->folders($argv[-1] // undef, 1); - @m = map { $match_cb->($_) } @k; - if (@m) { @f{@m} = @m } else { @f{@k} = @k } + for (@try) { + @f = $lms->folders($_, 1) and last; + } + push @k, @f; } - keys %f; + my @m = map { $match_cb->($_) } @k; + @m ? @m : @k; } no warnings 'once'; diff --git a/lib/PublicInbox/LeiQuery.pm b/lib/PublicInbox/LeiQuery.pm index 358574ea..3337e5d4 100644 --- a/lib/PublicInbox/LeiQuery.pm +++ b/lib/PublicInbox/LeiQuery.pm @@ -173,6 +173,8 @@ no query allowed on command-line with --stdin # shell completion helper called by lei__complete sub _complete_q { my ($self, @argv) = @_; + join('', @argv) =~ /\bL:\S*\z/ and + return eval { $self->_lei_store->search->all_terms('L') }; my @cur; my $cb = $self->lazy_cb(qw(forget-external _complete_)); while (@argv) { |