views:

247

answers:

2

I am using Term::Shell package to implement a CLI tool. This package provides a API: comp_CMD.

This function is invoked whenever the user presses the TAB. My requirement here is:

shell> stackTAB

over under

`shell>stack overTAB

flow sample junk

But the default comp_CMD provides only one set of TAB options like

shell> stack TAB

over under

`shell>stack overTAB

over under ### THE PROBLEM IS HERE

Instead of over under here, I want to get flow sample junk.

+3  A: 

With the comp_* style handlers one can only match one's completions against the last incomplete word. Fortunately, however, you can get the desired result by overriding the catch_comp function like below; it lets one match against whole command line:

my %completion_tree = (
    stack => { under => [],
               over  => [qw(flow sample junk)] }
);

sub catch_comp {
    my $o = shift;
    my ($cmd, $word, $line, $start) = @_;

    my $completed = substr $line, 0, $start;
    $completed =~ s/^\s*//;

    my $tree = \%completion_tree;
    foreach (split m'\s+', $completed) {
        last if ref($tree) ne 'HASH';
        $tree = $tree->{$_};
    }

    my @completions;
    $_ = ref($tree);
    @completions =      @$tree if /ARRAY/;
    @completions = keys %$tree if /HASH/;
    @completions =      ($tree)if /SCALAR/;

    return $o->completions($word, [@completions]);
}
Inshallah
thanks Inshalla... i am a newbie to Perl.. I have copied ur code in to mine.. Now the problem is i dunno what changes should i make in sample code and get the expected output.. Sorry, if i am asking for too much.. Can you just write the comp_CMD module for me?..
Anandan
You can just copy/paste the function above as it is, without modifications. Only the $completion_tree needs to be modified. If the syntax gives you problems have a look at http://perldoc.perl.org/perldata.html . It should actually be fairly obvious how to modify it, since the example above represents exactly the kind of completion you expect; just change "stack" to whatever your command is; "under" and "over" are your first parameters; "flow" etc. are second parameters, but only available if "over" is the first. You can grow the tree to arbitrary size.
Inshallah
I am able to use that now.. Thanks a lot Inshalla :) :)
Anandan
A: 

One more thing i want to add here..

After overriding rl_complete subroutine, we also have to override comp__ (Default subroutine called for TAB) to avoid repeated printing of the subcommands.

Anandan