File Coverage

blib/lib/MooseX/App/Plugin/ZshCompletion/Command.pm
Criterion Covered Total %
statement 79 79 100.0
branch 13 16 81.2
condition n/a
subroutine 5 5 100.0
pod 1 1 100.0
total 98 101 97.0


line stmt bran cond sub pod time code
1             package MooseX::App::Plugin::ZshCompletion::Command;
2             # ABSTRACT: Command class for MooseX::App::Plugin::ZshCompletion
3              
4 1     1   7 use Moose;
  1         2  
  1         8  
5 1     1   5493 use 5.010;
  1         4  
6             our $VERSION = '0.002_001'; # TRIAL VERSION
7              
8 1     1   6 use namespace::autoclean;
  1         3  
  1         6  
9 1     1   55 use MooseX::App::Command;
  1         2  
  1         7  
10              
11             command_short_description q(Zsh completion automator);
12              
13             sub zsh_completion {
14 1     1 1 4 my ($self,$app) = @_;
15              
16 1         2 my %command_map;
17 1         4 my $app_meta = $app->meta;
18 1         58 my $commands = $app_meta->app_commands;
19 1         9 my $command_list = join (' ', sort keys %{$commands});
  1         7  
20 1         2 my $package = __PACKAGE__;
21 1         28 my $prefix = $app_meta->app_base;
22              
23 1         64 my ($sec,$min,$hour,$mday,$mon,$year) = localtime(time);
24 1         5 $year += 1900;
25 1         6 $mday = sprintf('%02i',$mday);
26 1         4 $mon = sprintf('%02i',$mon+1);
27              
28 1         4 $prefix =~ tr/./_/;
29              
30 1         7 while (my ($command,$command_class) = each %$commands) {
31 4         16 Class::Load::load_class($command_class);
32 4         141 my @parameters = $app_meta->command_usage_attributes($command_class->meta,'parameter');
33 4         5629 my @options = $app_meta->command_usage_attributes($command_class->meta,[qw(option proto)]);
34 4         5461 $command_map{$command} = {
35             parameters => \@parameters,
36             options => \@options,
37             };
38             }
39              
40 1         3 my $syntax = '';
41 1         3 my $subcmd = '';
42 1         3 my $subcmd_functions = '';
43              
44 1         5 for my $command (sort keys %command_map) {
45 4         9 my $data = $command_map{ $command };
46 4         17 $subcmd .= <<"EOM";
47             $command)
48             _${prefix}_$command
49             ;;
50             EOM
51              
52 4         10 my $options = $command_map{ $command }->{options};
53 4         6 my $option_list = '';
54 4         7 my $parameter_list = '';
55 4         8 my $parameter_completion = '';
56              
57 4         8 my $i = 2;
58 4         8 for my $param (@{ $command_map{ $command }->{parameters} }) {
  4         10  
59 4         11 my $name = $param->cmd_usage_name;
60 4         360 my $doc = $param->documentation;
61              
62 4         29 my $comp = "_files";
63 4 50       114 if ($param->has_type_constraint) {
64 4         111 my $tc = $param->type_constraint;
65 4 100       42 if ($tc->isa('Moose::Meta::TypeConstraint::Enum')) {
66 3         5 my $values = join ' ', sort @{ $tc->values };
  3         73  
67 3         27 $comp = "compadd -X '$doc' $values";
68             }
69             }
70 4 50       113 my $position = $param->is_required ? $i : '*';
71 4         33 $parameter_list .= qq{ '$position: :->$name' \\\n};
72 4         12 $parameter_completion .= <<"EOM";
73             $name)
74             $comp
75             ;;
76             EOM
77 4         9 $i++;
78             }
79 4 100       11 if (length $parameter_completion) {
80 2         8 $parameter_completion = <<"EOM";
81             curcontext="\${curcontext%:*:*}:$prefix-cmd-\$words[1]:"
82              
83             case \$state in
84             $parameter_completion
85             esac
86             EOM
87             }
88              
89 4         38 for my $opt (@$options) {
90 10         33 my $name = $opt->cmd_usage_name;
91 10         1976 my @names = $opt->cmd_name_possible;
92 10         1697 my $doc = $opt->documentation;
93 10         77 $doc =~ s/'/'"'"'/g;
94              
95 10         28 my @opt = split ' ', $name;
96 10 100       23 if (@opt > 1) {
97             # '(-q --quiet)'{-q,--quiet}'[Show minimal output]' \
98 4         6 $option_list .= " '(@{[ @opt ]})'\{@{[ join ',', @opt ]}\}'\[$doc\]";
  4         18  
  4         18  
99             }
100             else {
101 6         18 $option_list .= " '$opt[0]\[$doc\]";
102             }
103 10 50       309 if ($opt->has_type_constraint) {
104 10         282 my $tc = $opt->type_constraint;
105 10 100       302 if ($tc->isa('Moose::Meta::TypeConstraint::Enum')) {
    100          
106 1         3 my $values = join ' ', sort @{ $tc->values };
  1         44  
107 1         73 $option_list .= ":$names[0]:($values)";
108             }
109             elsif ($opt->type_constraint->is_a_type_of('Bool')) {
110             }
111             else {
112 3         1512 $option_list .= ":$names[0]";
113             }
114             }
115 10         649 $option_list .= "' \\\n";
116             }
117 4         21 $subcmd_functions .= <<"EOM";
118             _${prefix}_$command() {
119             _arguments -C \\
120             '1: :->subcmd' \\
121             $parameter_list$option_list && ret=0
122              
123             $parameter_completion
124             }
125              
126             EOM
127             }
128              
129 1         29 $syntax .= <<"EOT";
130             #compdef $prefix
131              
132             # Built with $package on $year/$mon/$mday
133              
134             _$prefix() {
135             typeset -A opt_args
136             local curcontext="\$curcontext" state line context
137              
138             _arguments -s \\
139             '1: :->subcmd' \\
140             '*: :->args' \\
141             && ret=0
142              
143             case \$state in
144              
145             subcmd)
146             compadd help $command_list
147             ;;
148              
149             args)
150             curcontext="\${curcontext%:*:*}:$prefix-cmd-\$words[1]:"
151              
152             case \$line[1] in
153             $subcmd
154             help)
155             _${prefix}_help
156             esac
157              
158             esac
159             }
160              
161             $subcmd_functions
162             _${prefix}_help() {
163             compadd $command_list
164             }
165              
166             EOT
167              
168              
169 1         43 return MooseX::App::Message::Envelope->new(
170             MooseX::App::Message::Block->new({ body => $syntax })
171             );
172             }
173              
174             __PACKAGE__->meta->make_immutable;
175             1;
176              
177             __END__
178              
179             =head1 NAME
180              
181             MooseX::App::Plugin::ZshCompletion::Command - generates the zsh completion for MooseX::App::Plugin::ZshCompletion
182              
183             =head1 METHODS
184              
185             =over 4
186              
187             =item zsh_completion
188              
189             This method is doing the generation.
190              
191             =back
192              
193             =cut