use strict; use warnings; package BarnOwl::Completion::Util; use base qw(Exporter); our @EXPORT_OK = qw(complete_flags); use Getopt::Long; sub complete_flags { my $ctx = shift; my $no_args = shift; my $args = shift; my $default = shift; my %options = (); %options = @_ if @_; my $idx = 1; my $flag = undef; my $argct = 0; my $optsdone = 0; my %flags_seen; while($idx < $ctx->word) { my $word = $ctx->words->[$idx]; if($flag) { undef $flag; } elsif($word =~ m{^--}) { if($word eq '--') { $optsdone = 1; $idx++; last; } $flag = $word if(exists $args->{$word}); } elsif ($word =~ m{^-}) { $word = "-" . substr($word, -1); $flags_seen{$word} = 1; # record flag $flag = $word if(exists $args->{$word}); } else { $argct++; if ($options{stop_at_nonflag}) { $optsdone = 1; $idx++; last; } } $idx++; } # Account for any words we skipped $argct += $ctx->word - $idx; if($flag) { my $c = $args->{$flag}; if($c) { return $c->($ctx); } return; } else { my @opts = $optsdone ? () : (@$no_args, keys %$args); # filter out flags we've seen if needbe @opts = grep {!$flags_seen{$_}} @opts unless $options{repeat_flags}; return (@opts, $default ? ($default->($ctx, $argct)) : ()); } }