File Coverage

blib/lib/Getopt/App/Complete.pm
Criterion Covered Total %
statement 61 61 100.0
branch 17 18 94.4
condition 10 13 76.9
subroutine 12 12 100.0
pod 2 2 100.0
total 102 106 96.2


line stmt bran cond sub pod time code
1             package Getopt::App::Complete;
2 2     2   925 use feature qw(:5.16);
  2         5  
  2         396  
3 2     2   14 use strict;
  2         3  
  2         41  
4 2     2   8 use warnings;
  2         3  
  2         93  
5 2     2   10 use utf8;
  2         3  
  2         15  
6 2     2   96 use Cwd qw(abs_path);
  2         4  
  2         148  
7 2     2   11 use File::Basename qw(basename);
  2         4  
  2         304  
8 2     2   11 use Exporter qw(import);
  2         3  
  2         3054  
9              
10             our @EXPORT_OK = qw(complete_reply generate_completion_script);
11              
12             require Getopt::App;
13 2     2   18 our $call_maybe = do { no warnings qw(once); $Getopt::App::call_maybe };
  2         4  
  2         314  
14              
15             sub complete_reply {
16 10     10 1 17 my $app = shift;
17 10         51 my ($script, @argv) = split /\s+/, $ENV{COMP_LINE};
18              
19             # Recurse into subcommand
20 2     2   12 no warnings qw(once);
  2         4  
  2         878  
21 10         20 my $depth = $Getopt::App::DEPTH;
22 10   100     31 my $subcommands = $app->$call_maybe('getopt_subcommands') || [];
23 10 100 100     348 if ($argv[$depth] and $argv[$depth] =~ m!^\w! and @$subcommands) {
      66        
24 4         21 my $argv = [@argv[$depth, $#argv]];
25 4         14 for my $subcommand (@$subcommands) {
26 15 100       57 next unless $argv[$depth] eq $subcommand->[0];
27 3   66     19 my $cb = $Getopt::App::APPS{$subcommand->[1]} ||= $app->$call_maybe(getopt_load_subcommand => $subcommand, $argv);
28 3         7 local $Getopt::App::SUBCOMMAND = $subcommand;
29 3         16 return $cb->([@$argv[1 .. $#$argv]]);
30             }
31             }
32              
33             # List matching subcommands
34 7 100       81 my $got = substr($ENV{COMP_LINE}, 0, $ENV{COMP_POINT}) =~ m!(\S+)$! ? $1 : '';
35 7         22 for my $subcommand (@$subcommands) {
36 24 100       259 say $subcommand->[0] if index($subcommand->[0], $got) == 0;
37             }
38              
39             # List matching command line options
40 2     2   18 no warnings q(once);
  2         5  
  2         1616  
41 7 50       16 for (@{$Getopt::App::OPTIONS || []}) {
  7         28  
42 21         45 my $opt = $_;
43 21         121 $opt =~ s!(=[si][@%]?|\!|\+|\s)(.*)!!;
44 21         77 ($opt) = sort { length $b <=> length $a } split /\|/, $opt; # use --version instead of -v
  3         12  
45 21 100       63 $opt = length($opt) == 1 ? "-$opt" : "--$opt";
46 21 100       62 next unless index($opt, $got) == 0;
47 13         414 say $opt;
48             }
49              
50 7         132 return 0;
51             }
52              
53             sub generate_completion_script {
54 4     4 1 294042 my $script_path = abs_path($0);
55 4         2306 my $script_name = basename($0);
56 4 100 50     45 my $shell = ($ENV{SHELL} || 'bash') =~ m!\bzsh\b! ? 'zsh' : 'bash';
57              
58 4 100       10 if ($shell eq 'zsh') {
59 3         20 my $function = '_' . $script_name =~ s!\W!_!gr;
60 3         36 return <<"HERE";
61             $function() {
62             read -l; local l="\$REPLY";
63             read -ln; local p="\$REPLY";
64             reply=(\$(COMP_LINE="\$l" COMP_POINT="\$p" COMP_SHELL="zsh" $script_path));
65             };
66              
67             compctl -f -K $function $script_name;
68             HERE
69             }
70             else {
71 1         15 return "complete -o default -C $script_path $script_name;\n";
72             }
73             }
74              
75             1;
76              
77             =encoding utf8
78              
79             =head1 NAME
80              
81             Getopt::App::Complete - Add auto-completion to you Getopt::App script
82              
83             =head1 SYNOPSIS
84              
85             use Getopt::App -complete;
86              
87             run(
88             'h # Print help',
89             'completion-script # Print autocomplete script',
90             sub {
91             my ($app, @args) = @_;
92             return print generate_completion_script() if $app->{'completion-script'};
93             return print extract_usage() if $app->{h};
94             },
95             );
96              
97             =head1 DESCRIPTION
98              
99             L contains helper functions for adding auto-completion to
100             your L powered script.
101              
102             This module is currently EXPERIMENTAL.
103              
104             =head1 EXPORTED FUNCTIONS
105              
106             =head2 complete_reply
107              
108             $int = complete_reply($app_obj);
109              
110             This function is the default behaviour when L is called with
111             C and C set.
112              
113             This function will print completion options based on C and
114             C to STDOUT and is aware of subcommands.
115              
116             =head2 generate_completion_script
117              
118             $str = generate_completion_script();
119              
120             This function will detect if the C or C shell is in use and return
121             the appropriate initialization commands.
122              
123             =head1 SEE ALSO
124              
125             L
126              
127             =cut