App-Chained
view release on metacpan or search on metacpan
lib/App/Chained.pm view on Meta::CPAN
Direction about how to use the completion scritp is contained in the generated script.
The completion will work for the top application till a command is input on the command line after that the completion is for the command.
=head3 command specific options
Your sub commands can define an B<options> field. The field should be set to a subroutine reference that returns a string of options the sub command
accepts. The format should be I<-option_name>. One option perl line.
Here is an example of how I added completion to a set sub commands (8 of them). The sub commands do not have a completion script
and rely on the wrapper for completion.
I first set the B<options> field:
{
description => ...
run => ...
...
options => sub {return `$name --dump_options`},
}
I am using the sub command itself to generate the options. This way I don't have to maintain the list by hand (which is possible).
Modifying the sub command itself was trivial and very quick. I modified the following code (example in one of thesub commands)
die 'Error parsing options!'unless
GetOptions
(
'master_template_file=s' => \$master_template_file,
'h|help' => \&display_help,
) ;
to be
die 'Error parsing options!'unless
GetOptions
(
'master_template_file=s' => \$master_template_file,
'h|help' => \&display_help,
'dump_options' =>
sub
{
print join "\n", map {"-$_"}
qw(
master_template_file
help
) ;
exit(0) ;
},
) ;
Modfying the height or so scripts took only a few minutes.
Noiw I have command completion for all the sub command. Here is an example:
nadim@naquadim Arch (master)$ ra show -[tab]
-format -include_loaded_from -master_categories_file
-help -include_not_found -master_template_file
-include_categories -include_statistics -remove_empty_requirement_field_in_categories
-include_description_data -include_type -requirement_fields_filter_file
The I<show> sub command is two order of magnitude easier to use with completion.
I<Arguments> - None
I<Returns> - Nothing - exits with status code B<1> after emitting the completion script on stdout
I<Exceptions> - None - Exits the program.
=cut
my ($self) = @_ ;
$self->get_options_definitions() ; # generates $self->{getopt_definitions}
my @options = map { s/=.$//sxm ; "\t-$_ => 0," } keys %{$self->{getopt_definitions}} ;
my @command_options ;
my $sub_apps = $self->{sub_apps} ;
if(defined $sub_apps)
{
while(my ($sub_app_name, $sub_app) = each %{$sub_apps})
{
my @sub_app_options ;
if(exists $sub_app->{options} && 'CODE' eq ref($sub_app->{options}))
{
@sub_app_options= map {chomp ; $_} $sub_app->{options}($self, $sub_app, []) ;
}
push @command_options, "\t$sub_app_name => [qw(@sub_app_options)]," ;
}
}
use File::Basename ;
my ($basename, $path, $ext) = File::Basename::fileparse($PROGRAM_NAME, ('\..*')) ;
my $application_name = $basename . $ext ;
local $| = 1 ;
my $complete_script = <<"COMPLETION_SCRIPT" ;
#The perl script has to be executable and somewhere in the path.
#This script was generated using used your application name
#Add the following line in your I<~/.bashrc> or B<source> them:
_${application_name}_perl_completion()
{
local old_ifs="\${IFS}"
local IFS=\$'\\n';
COMPREPLY=( \$(${application_name}_perl_completion.pl \${COMP_CWORD} \${COMP_WORDS[\@]}) );
IFS="\${old_ifs}"
return 1;
}
complete -o default -F _${application_name}_perl_completion $application_name
( run in 2.260 seconds using v1.01-cache-2.11-cpan-ff9377addf4 )