1
2package Term::Bash::Completion::Generator ;
3
4use strict;
5use warnings ;
6use Carp qw(carp croak confess) ;
7
8BEGIN
9{
10use Sub::Exporter -setup =>
11	{
12	exports => [ qw() ],
13	groups  =>
14		{
15		all  => [ qw() ],
16		}
17	};
18
19use vars qw ($VERSION);
20$VERSION     = '0.02';
21}
22
23#-------------------------------------------------------------------------------
24
25=head1 NAME
26
27Term::Bash::Completion::Generator - Generate bash completion scripts
28
29=head1 SYNOPSIS
30
31  # use default bash completion options
32  generate_bash_completion_function('my_command', ['option1', ''option2']) ;
33
34  # fine tune with the bash completion options
35  generate_bash_completion_function('my_command', ['option1', ''option2'], '-*', 0, '-o plusdirs')
36
37=head1 DESCRIPTION
38
39Generate bash completion functions or perl scripts to dynamically provide completion for an application.
40
41=head1 DOCUMENTATION
42
43If you application or scripts have more than one or two options and you run a bash shell, it is
44advisable you provide a completion file for your application.
45
46A completion file provides information to bash so when your user presses [tab], on the command line,
47possible completion is provided to the user.
48
49This module provide you with subroutines to create the completion scripts. The completion scripts are
50either simple bash functions or scripts that allow you to dynamically generate completion. The scripts
51can be written in any language. This module generate scripts that are written in perl.
52
53The perl scripts can be generated  by calling the subroutine i this module or by running
54the I<generate_perl_completion_script> script installed with this module.
55
56The generated scripts can provide completion for applications written in any language. A good place to
57generate completion is in your I<Build.PL> or I<Makefile.PL>. Remember to test your completions too.
58
59=head1 BASH COMPLETION DOCUMENTATION
60
61Run 'man bash' on your prompt and search for 'Programmable Completion'.
62
63bash-completion-20060301.tar.gz library, an older but useful archive of completion functions for common
64commands.
65
66=head1 SUBROUTINES/METHODS
67
68=cut
69
70
71#-------------------------------------------------------------------------------
72
73#~ sub generate_bash_completion_function_using_perl_script
74#~ {
75#~ # generate a bash function that calls a perl script
76
77#~ #check if one can get the whole command line to the perl script
78
79#~ }
80
81#-------------------------------------------------------------------------------
82
83sub generate_perl_completion_script
84{
85
86=head2 generate_perl_completion_script($command, \@completion_list)
87
88Generates a perl script that can be used to dynamically generate completion for the bash
89command line.
90
91L<Tree::Trie> is used in the script to do the basic look-up. L<Tree::Trie> was installed as
92dependency to this module. Modify the generated script to implement your completion logic.
93
94You can also use the I<generate_perl_completion_script> script to create the perl completion
95script from the command line.
96
97I<Arguments>
98
99=over 2
100
101=item * $command - a string containing the command name
102
103=item * \@completion_list - list of options to create completion for
104
105the options can be simple strings or a L<Getopt::Long> specifications
106
107=back
108
109I<Returns> - an array containing:
110
111=over 2
112
113=item * a string containing the bash completion command
114
115=item * a string containing the perl script
116
117=back
118
119I<Exceptions> - carps if $command is not defined
120
121=cut
122
123my ($command, $completion_list) = @_ ;
124
125croak 'Argument "$command" not defined' unless defined $command ; ## no critic ValuesAndExpressions::RequireInterpolationOfMetachars
126
127my $bash_completion_arguments = "-o default -C perl_completion_script $command" ;
128my $bash_completion_command = "complete $bash_completion_arguments" ;
129
130my $perl_completion_script = <<'EOC' ;
131#! /usr/bin/perl
132
133=pod
134
135B<source> the following line in your I<~/.bashrc>:
136
137EOC
138
139$perl_completion_script .= <<"EOC" ;
140B<complete> $bash_completion_arguments
141
142EOC
143
144$perl_completion_script .= <<'EOC' ;
145Replace I<perl_completion_script> with the name you saved the script under. The script has to
146be executable and somewhere in the path.
147
148The script will receive these arguments from bash:
149
150@ARGV
151|- 0 = command
152|- 1 = word_to_complete
153`- 2 = word_before_the_word_to_complete
154
155You return possible completion you want separated by I<\n>. Return nothing if you
156want the default bash completion to be run which is possible because of the <-o defaul>
157passed to the B<complete> command.
158
159Note! You may have to re-run the B<complete> command after you modify your perl script.
160
161=cut
162
163use strict;
164use Tree::Trie;
165
166my @completions =
167	qw(
168EOC
169
170if(defined $completion_list)
171	{
172	$completion_list = de_getop_ify_list($completion_list) ;
173	}
174else
175	{
176	$completion_list = [qw(aeode calliope clio erato euterpe melete melpomene mneme polymnia terpsichore thalia urania)]
177	}
178
179for my $option (@{$completion_list})
180	{
181	if(1 == length($option))
182		{
183		$perl_completion_script .= "\t-$option\n" ;
184		}
185	else
186		{
187		$perl_completion_script .= "\t--$option\n" ;
188		}
189	}
190
191$perl_completion_script .= <<'EOC' ;
192	) ;
193
194my($trie) = new Tree::Trie;
195$trie->add(@completions) ;
196
197if(defined $ARGV[1])
198	{
199	if(substr($ARGV[1], 0, 1) eq '-')
200		{
201		print join("\n", $trie->lookup($ARGV[1])) ;
202		}
203	}
204else
205	{
206	print join("\n", $trie->lookup('')) ;
207	}
208EOC
209
210return($bash_completion_command, $perl_completion_script) ;
211}
212
213sub generate_bash_completion_function
214{
215
216=head2 generate_bash_completion_function($command, \@completion_list, $completion_prefix, $single_and_double_dash, $complete_options)
217
218Generates a bash function that provides completion for the options passed as parameter.
219The options can be simple strings like 'output_directory' or 'a' or L<Getopt::Long> specifications
220like 'j|jobs=i', 'd|display_documentation:s', or 'o'.
221
222Note that the options do not have any dash at the start.
223
224I<Arguments>
225
226=over 2
227
228=item * $command - a string containing the command name
229
230=item * \@completion_list - list of options to create completion for
231
232the options can be simple strings or a L<Getopt::Long> specifications
233
234=item * $completion_prefix - see bash manual ; default is '-*'
235
236=item * $single_and_double_dash - boolean variable ; default is 1
237
2380 - single dash for single letter options, double dash for multiple letters options
2391 - all options have single and double dash
240
241=item * $complete_options - string containing the options passed to I<complete> ; default is '-o default'
242
243=back
244
245I<Returns> - a string containing the bash completion script
246
247I<Exceptions> - carps if $command is not defined
248
249=cut
250
251my ($command, $completion_list, $completion_prefix, $single_and_double_dash, $complete_options) = @_ ;
252
253croak 'Argument "$command" not defined' unless defined $command ; ## no critic ValuesAndExpressions::RequireInterpolationOfMetachars
254
255$completion_prefix = q{-*} unless defined $completion_prefix ;
256$single_and_double_dash = 1 unless defined $single_and_double_dash ;
257$complete_options = '-o default' unless defined $complete_options ;
258
259my $completion_function_name = "_${command}_bash_completion" ;
260$completion_function_name =~ s/[^a-zA-Z0-9_]/_/gsmx ;
261
262my $completion_function = "$completion_function_name()\n" ;
263
264$completion_function .= <<'EOH' ;
265{
266	local cur
267
268	COMPREPLY=()
269	cur=${COMP_WORDS[COMP_CWORD]}
270EOH
271
272$completion_function .= <<"EOH" ;
273	if [[ "\$cur" == $completion_prefix ]]; then
274EOH
275
276$completion_function .= <<'EOH' ;
277		COMPREPLY=( $( compgen -W '\
278EOH
279
280$completion_list = de_getop_ify_list($completion_list) ;
281
282for my $option (@{$completion_list})
283	{
284	if($single_and_double_dash)
285		{
286		$completion_function .= "\t\t\t-$option --$option \\\n" ;
287		}
288	else
289		{
290		if(1 == length($option))
291			{
292			$completion_function .= "\t\t\t-$option \\\n" ;
293			}
294		else
295			{
296			$completion_function .= "\t\t\t--$option \\\n" ;
297			}
298		}
299	}
300
301$completion_function .= <<"EOF" ;
302			' -- \$cur ) )
303	fi
304
305	return 0
306}
307
308complete -F $completion_function_name $complete_options $command
309EOF
310
311return $completion_function ;
312}
313
314#-------------------------------------------------------------------------------
315
316sub de_getop_ify_list
317{
318
319=head2 de_getop_ify_list(\@completion_list)
320
321Split L<Getopt::Long> option definitions and remove type information
322
323I<Arguments>
324
325=over 2
326
327=item * \@completion_list - list of options to create completion for
328
329the options can be simple strings or a L<Getopt::Long> specifications
330
331=back
332
333I<Returns> - an array reference
334
335I<Exceptions> - carps if $completion_list is not defined
336
337=cut
338
339my ($completion_list) = @_ ;
340
341croak unless defined $completion_list ;
342
343my @de_getopt_ified_list ;
344
345for my $switch (@{$completion_list})
346	{
347	my @switches = split(/\|/sxm, $switch) ;
348
349	#~ print "$switch => \n" ;
350	for (@switches)
351		{
352		s/=.*$//sxm ;
353		s/:.*$//sxm ;
354
355		push @de_getopt_ified_list, $_ ;
356		}
357	}
358
359return \@de_getopt_ified_list ;
360}
361
362#-------------------------------------------------------------------------------
363
3641 ;
365
366=head1 BUGS AND LIMITATIONS
367
368None so far.
369
370=head1 AUTHOR
371
372	Nadim ibn hamouda el Khemir
373	CPAN ID: NH
374	mailto: nadim@cpan.org
375
376=head1 LICENSE AND COPYRIGHT
377
378This program is free software; you can redistribute
379it and/or modify it under the same terms as Perl itself.
380
381=head1 SUPPORT
382
383You can find documentation for this module with the perldoc command.
384
385    perldoc Term::Bash::Completion::Generator
386
387You can also look for information at:
388
389=over 4
390
391=item * AnnoCPAN: Annotated CPAN documentation
392
393L<http://annocpan.org/dist/Term-Bash-Completion-Generator>
394
395=item * RT: CPAN's request tracker
396
397Please report any bugs or feature requests to  L <bug-term-bash-completion-generator@rt.cpan.org>.
398
399We will be notified, and then you'll automatically be notified of progress on
400your bug as we make changes.
401
402=item * Search CPAN
403
404L<http://search.cpan.org/dist/Term-Bash-Completion-Generator>
405
406=back
407
408=head1 SEE ALSO
409
410L<Getopt::Long>
411
412L<Tree::Trie>
413
414L<http://fvue.nl/wiki/Bash_completion_lib>
415
416=cut
417