qbxk has asked for the wisdom of the Perl Monks concerning the following question:

This question is less perl related, but I believe relevant to many monks here.

I have a script that acts on any number of files in a particular directory, and I frequently find myself typing the name of the script, space, tab tab, and seeing the files in the directory i'm in, harrumph! What I'd really like is to emulate the bash tabbing features, but have my script do the "deciding" on what should be shown. Is there a way to override the "tabbing" in bash to call my script with a special parameter indicating that i want tab completion features to run (and pass in my partially typed argument so it can do this properly).

I hope this is phrased properly, need clarification?

It's not what you look like, when you're doin' what you’re doin'.
It's what you’re doin' when you’re doin' what you look like you’re doin'!
     - Charles Wright & the Watts 103rd Street Rhythm Band, Express yourself

2006-08-24 Retitled by holli, as per Monastery guidelines
Original title: 'Bash Tabbing'

Replies are listed 'Best First'.
Re: (OT) Bash Tabbing
by zigdon (Deacon) on Aug 23, 2006 at 21:00 UTC
    I'm almost 100% sure you - I use zsh, and I know you can do it there. I think there's nothing here that's zsh specific though:
    function hosts {set -A reply $($HOME/bin/gethosts)} compctl -K hosts -x 'c[-1,-l]' -u -- ping ssh telnet traceroute
    This makes tab completion call my gethosts script whenever I try to tab as the first argument of ping, ssh, telent or traceroute. My gethosts script is pretty simple:
    #!/usr/bin/perl -w use strict; my $HOME= $ENV{HOME}; open (HOSTS, "$HOME/.ssh/known_hosts") or exit; my @hosts = <HOSTS>; close HOSTS; foreach my $line (@hosts) { chomp($line); my ($name) = split /\s+/, $line, 2; my @names = split /,/, $name; foreach (@names) { print "$_ "; } }
    So it returns an bash array (a list of space separated strings) of all the hostnames and ips in my .know_hosts file.

    -- zigdon

Re: (OT) Bash Tabbing
by imp (Priest) on Aug 23, 2006 at 20:31 UTC
    You should look through the documentation for the bash completion project. It's very flexible, but I can't recall offhand if it does what you want.
      If you want to customize the completion on a per-script basis, then one way to approach this problem would be to use bash_completion with a custom completion function. This function could parse the given perl script for completion hints which could be passed to compgen (a bash builtin).

      I haven't worked with bash_completion enough to provide a working example unfortunately. One potential shortcoming would be that you need to tell bash when to run this completion code. This is typically done by specifying the completion logic for a given command. (e.g. perl is handled by the _perl function).

      Example code with completion config in comments

      #!/usr/bin/perl #complete -G '*.bak'
      And awk to extract it:
      awk 'NR == 1 {next} /^\#complete/ {print} /^[^#]/ {exit}' $filename
      Explanation of the awk:
      1. NR == 1 {next}
        Skip the first record
      2. /^\#complete/ {print}
        Print any lines that start with #complete
      3. /^^#/ {exit}
        Stop processing when a non-comment line is reached
Re: (OT) Bash Tabbing
by ikegami (Patriarch) on Aug 23, 2006 at 20:48 UTC
Re: (OT) Bash Tabbing
by shmem (Chancellor) on Aug 23, 2006 at 21:04 UTC
    From what you write it's not all that clear - is your script interactive?
    Have a look at Term::ReadLine::Gnu, then.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
      no, not interactive. just trying to redirect the bash "tab" to someplace i have control over, that is:
      overriding the default behavior of using the current directory's contents for the bash completion list.

      I'm pretty sure imp nailed it (++), ikegami might have, but that's only if i wanted interactive. It'd be supremely cool to have a module that did just override bash behavior like the bash completion project does, but i have no clue how you could possibly create such a beast

      It's not what you look like, when you're doin' what you’re doin'.
      It's what you’re doin' when you’re doin' what you look like you’re doin'!
           - Charles Wright & the Watts 103rd Street Rhythm Band, Express yourself