Thanks LanX for not presenting the solution but sparse hints, seriously.
The best of such hints was: Have a look at Attribs.
My problem was that i was relaying on the function readline::rl_basic that, as explained by LanX, is used internally by Term::ReadLine::Perl and a strange behaviour (still obscure to me) happened: the code presented above seems to reveal that this function is not defined the first time we check for it but is defined in the continue block.
To overcomplicate things, win32 is strange and dumb as console (we need some hacks at it..).
The solution is to access $term->Attribs->{completion_function} and configure manually that feature.
Here i present a working example to play with and that demonstrate what stated above.
#!perl
use strict;
use warnings;
BEGIN {
# you can force Term::ReadLine to load the ::Perl
# by setting the ENV PERL_RL variable
# but you have to do it in a begin block
# before the use statement
# try to comment next line: probably ::Perl will be loaded
# anyway if it is installed
# try to set to a non available sub module
# see details: https://metacpan.org/pod/Term::ReadLine#ENVIRON
+MENT
$ENV{PERL_RL}="Perl";
# on win32 systems it ENV TERM is 'dumb'
# autocompletion is not possible.
# try to comment next line on win32 and watch how does not wor
+k
# see also http://bvr.github.io/2010/11/term-readline/
$ENV{TERM} = 'not dumb' if $^O eq 'MSWin32';
}
use Term::ReadLine;
my $term=Term::ReadLine->new("test");
# Term::ReadLine is a wrapper module: it initilizes an Attribs hasref
# internally used to fill in the right configuration.
# You can use this hashref to set autompletion manually. As i did here
+.
#
# YOU MUST NOT USE readline::rl_basic_commands DIRECTLY!
#
# you cannot print anything from hashref returned by $term->Attribs
#foreach my $k (keys $term->Attribs){print "$k ${$term->Attribs}{$k}\n
+"}
my %cmd = (run1=>1, Rename1=>1, quit1=>1, QUONDAM1=>1);
my %alt = (run_2=>1,Rename_2=>1,quit_2=>1,QUONDAM_2=>1);
my $hr = \%cmd; # default hashref is a ref to %cmd
# first time initialization of autocompletion
&define_completion_func($hr);
print "The Term::ReadLine effective module loaded is: ",$term->ReadLin
+e,"\n";
print <<"END";
There are 2 sets of commands available:
\%cmd QUONDAM1 Rename1 quit1 run1
\%alt QUONDAM_2 Rename_2 quit_2 run_2
You can switch to alternates one entering 'alt'
and switch back with 'cmd'
TAB completion works and is set case insesitive
END
while ( defined ( $_ = $term->readline( 'prompt>') ) ) {
/^$/ ? next : chomp;
s/\s+//g;
if ($_ eq 'cmd'){ print "switching hashref to \%cmd\n"; $hr =
+\%cmd }
elsif ($_ eq 'alt'){ print "switching hashref to \%alt\n"; $hr =
+\%alt }
elsif (exists $$hr{$_} ) {print "OK $_ is defined in the current
+hashref of commands\n"}
else {next}
}
continue{ &define_completion_func($hr);}
sub define_completion_func {
my $cur_hr = shift;
# is time to access the $term->Attribs and set
# the sub that will be used to do autocompletion
# This version is case insensitive because of the i modifier
$term->Attribs->{completion_function} = sub {
my ($text, $line, $start) = @_;
# uncomment next line to see debug stuff while you stress
+autocomplete
#print 'DEBUG: $text, $line, $start = >'.(join '< >',$text
+, $line, $start)."<\n";
return grep { /^$text/i } sort keys %$cur_hr ;
};
}
HtH L*
There are no rules, there are no thumbs..
Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
|