—#!perl
use
5.010;
use
strict;
use
warnings;
use
Log::ger;
BEGIN {
$ENV
{TRACE} = 1 }
use
Getopt::Long;
our
$AUTHORITY
=
'cpan:PERLANCAR'
;
# AUTHORITY
our
$DATE
=
'2022-01-16'
;
# DATE
our
$DIST
=
'App-CompleteUtils'
;
# DIST
our
$VERSION
=
'0.180'
;
# VERSION
sub
_shell_quote_arg {
# pass some strings unquoted: foo=bar is quoted into 'foo=bar' by
# String::ShellQuote; skip quoting it
#say "D:<$_[0]>";
if
(
$_
[0] =~ /\A[A-Za-z0-9_=^-]+\z/) {
return
$_
[0];
}
else
{
return
String::ShellQuote::shell_quote(
$_
[0]);
}
}
my
%Opts
= (
shell
=>
undef
,
);
my
@inc
;
Getopt::Long::Configure(
'no_ignore_case'
,
'bundling'
,
'no_permute'
,
'pass_through'
,
'auto_help'
,
'auto_version'
);
GetOptions(
'include|I=s'
=>
sub
{
unshift
@inc
,
$_
[1];
},
'shell|s=s'
=> \
$Opts
{shell},
'bash'
=>
sub
{
$Opts
{shell} =
'bash'
},
'tcsh'
=>
sub
{
$Opts
{shell} =
'tcsh'
},
'fish'
=>
sub
{
$Opts
{shell} =
'fish'
},
'zsh'
=>
sub
{
$Opts
{shell} =
'zsh'
},
);
@ARGV
or
die
"testcomp: Please specify script to run as first argument\n"
;
my
$script
=
shift
@ARGV
;
if
(!(-f
$script
) &&
$script
!~ m!/!) {
my
$script_p
= which(
$script
)
or
die
"testcomp: Script '$script' not found in PATH\n"
;
$script
=
$script_p
;
}
unless
(
$Opts
{shell}) {
my
$shell
= Shell::Guess->running_shell;
$shell
=
"tcsh"
if
$shell
eq
'c'
;
$shell
=
"zsh"
if
$shell
eq
'z'
;
$Opts
{shell} =
$shell
;
}
my
$comp_line
=
"$script "
;
if
(
@ARGV
== 1 &&
$ARGV
[0] =~ /\s/) {
# user types: scriptname 'arg1 arg2 ...'. we should split the quoted args
$comp_line
.=
join
(
" "
,
@ARGV
);
}
else
{
# user types: scriptname 'arg1' 'arg two'. we should re-quote to avoid the
# space inside arg value to split args.
$comp_line
.=
join
(
" "
,
map
{_shell_quote_arg(
$_
)}
@ARGV
);
}
my
$comp_point
;
if
(
$comp_line
=~ /\^/) {
$comp_point
=
index
(
$comp_line
,
'^'
);
$comp_line
=~ s/\^//;
}
else
{
$comp_point
=
length
(
$comp_line
);
}
my
@cmd
= ($^X, (
map
{
"-I$_"
}
@inc
),
"-MLog::ger::Level::FromEnv"
,
"-MLog::ger::Output=Screen,colorize_tags,1"
,
$script
);
if
(
$Opts
{shell} eq
'tcsh'
) {
log_trace(
"[testcomp] COMMAND_LINE=<%s>"
,
$comp_line
);
$ENV
{COMMAND_LINE} =
$comp_line
;
}
else
{
log_trace(
"[testcomp] COMP_LINE=<%s>, COMP_POINT=%d"
,
$comp_line
,
$comp_point
);
$ENV
{COMP_LINE} =
$comp_line
;
$ENV
{COMP_POINT} =
$comp_point
;
}
log_trace(
"[testcomp] exec(): %s"
, \
@cmd
);
exec
@cmd
;
# ABSTRACT: Test your tab completion
# PODNAME: testcomp
__END__
=pod
=encoding UTF-8
=head1 NAME
testcomp - Test your tab completion
=head1 VERSION
This document describes version 0.180 of testcomp (from Perl distribution App-CompleteUtils), released on 2022-01-16.
=head1 SYNOPSIS
Usage (place caret sign (C<^>) somewhere to place cursor):
% testcomp [testcomp-options] -- <your-script> [your-script-options]^ ...
% testcomp [testcomp-options] -- <your-script> '[your-script-options]^ ...'
Examples:
% testcomp -- yourscript --opt1 val --opt2
% testcomp -Ilib -- 'yourscript --opt1^ --opt2 val'
=head1 DESCRIPTION
This utility will run your script (finding it in C<PATH> if not found in current
directory) while setting C<COMP_LINE> and C<COMP_POINT> to test how your script
will perform shell completion. In addition to that, it will also load
L<Log::ger::Output::Screen> and set C<TRACE=1> to let you see trace log
messages.
You can place caret sign (C<^>) somewhere in the argument to place cursor (set
C<COMP_POINT>)>. If no caret sign is present, C<COMP_POINT> is put at the end of
C<COMP_LINE>.
=head1 OPTIONS
=head2 --include=dir, -I
Like Perl's C<-I>.
=head2 --shell=SHELL, -s
Set shell. Currently this has a single effect: if shell is set to C<tcsh>, then
C<COMMAND_LINE> will be set for the program instead of C<COMP_LINE> and
C<COMP_POINT>. If unspecified, will be detected using C<<
Shell::Guess->running_shell >>.
=head2 --bash
Shortcut for C<--shell=bash>.
=head2 --fish
Shortcut for C<--shell=fish>.
=head2 --tcsh
Shortcut for C<--shell=tcsh>.
=head2 --zsh
Shortcut for C<--shell=zsh>.
=head1 HOMEPAGE
Please visit the project's homepage at L<https://metacpan.org/release/App-CompleteUtils>.
=head1 SOURCE
Source repository is at L<https://github.com/perlancar/perl-App-CompleteUtils>.
=head1 SEE ALSO
L<App::CompleteUtils>
You can use this utility to test scripts using these frameworks:
L<Perinci::CmdLine>, L<Getopt::Long::Complete>, L<Getopt::Long::Subcommand>. But
actually all scripts which can complete itself by detecting C<COMP_LINE> and
C<COMP_POINT> can be tested.
=head1 AUTHOR
perlancar <perlancar@cpan.org>
=head1 CONTRIBUTING
To contribute, you can send patches by email/via RT, or send pull requests on
GitHub.
Most of the time, you don't need to build the distribution yourself. You can
simply modify the code, then test via:
% prove -l
If you want to build the distribution (e.g. to try to install it locally on your
system), you can install L<Dist::Zilla>,
L<Dist::Zilla::PluginBundle::Author::PERLANCAR>, and sometimes one or two other
Dist::Zilla plugin and/or Pod::Weaver::Plugin. Any additional steps required
beyond that are considered a bug and can be reported to me.
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2022, 2020, 2018, 2017, 2016, 2015, 2014 by perlancar <perlancar@cpan.org>.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=head1 BUGS
Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=App-CompleteUtils>
When submitting a bug or request, please include a test-file or a
patch to an existing test-file that illustrates the bug or desired
feature.
=cut