<title>An Introduction to Programmable Completion</title>

    <para>The <firstterm>programmable completion</firstterm> feature in
      Bash permits typing a partial command, then pressing the
      <keycap>[Tab]</keycap> key to auto-complete the command sequence.

      <footnote><para>This works only from the <firstterm>command
        line</firstterm>, of course, and not within a
        script.</para></footnote>

      If multiple completions are possible, then <keycap>[Tab]</keycap>
      lists them all. Let's see how it works.</para>

      <para>
      <screen>
<prompt>bash$ </prompt><userinput>xtra[Tab]</userinput>
<computeroutput>xtraceroute       xtrapin           xtrapproto
 xtraceroute.real  xtrapinfo         xtrapreset
 xtrapchar         xtrapout          xtrapstats</computeroutput>


<prompt>bash$ </prompt><userinput>xtrac[Tab]</userinput>
<computeroutput>xtraceroute       xtraceroute.real</computeroutput>


<prompt>bash$ </prompt><userinput>xtraceroute.r[Tab]</userinput>
<computeroutput>xtraceroute.real</computeroutput>
      </screen>
      </para>

    <para>Tab completion also works for variables and path names.</para>

      <para>
      <screen>
<prompt>bash$ </prompt><userinput>echo $BASH[Tab]</userinput>
<computeroutput>$BASH                 $BASH_COMPLETION      $BASH_SUBSHELL
 $BASH_ARGC            $BASH_COMPLETION_DIR  $BASH_VERSINFO
 $BASH_ARGV            $BASH_LINENO          $BASH_VERSION
 $BASH_COMMAND         $BASH_SOURCE</computeroutput>


<prompt>bash$ </prompt><userinput>echo /usr/local/[Tab]</userinput>
<computeroutput>bin/     etc/     include/ libexec/ sbin/    src/     
 doc/     games/   lib/     man/     share/</computeroutput>
      </screen>
      </para>


    <para><anchor id="completeref"></para>

    <para>The Bash <command>complete</command> and
      <command>compgen</command> <link
      linkend="builtinref">builtins</link> make it
      possible for <firstterm>tab completion</firstterm> to
      recognize partial <firstterm>parameters</firstterm> and
      <firstterm>options</firstterm> to commands. In a very simple case,
      we can use <command>complete</command> from the command-line to
      specify a short list of acceptable parameters.</para>


  <screen>
<prompt>bash$ </prompt><userinput>touch sample_command</userinput>
<prompt>bash$ </prompt><userinput>touch file1.txt file2.txt file2.doc file30.txt file4.zzz</userinput>
<prompt>bash$ </prompt><userinput>chmod +x sample_command</userinput>
<prompt>bash$ </prompt><userinput>complete -f -X '!*.txt' sample_command</userinput>


<prompt>bash$ </prompt><userinput>./sample[Tab][Tab]</userinput>
<computeroutput>sample_command</computeroutput>
<computeroutput>file1.txt   file2.txt   file30.txt</computeroutput>
  </screen>

    <para>The <option>-f</option> option to
      <firstterm>complete</firstterm> specifies filenames,
      and <option>-X</option> the filter pattern.</para>

    <para><anchor id="compgenref"></para>

    <para>For anything more complex, we could write a script that
      specifies a list of acceptable command-line parameters.
      The <command>compgen</command> builtin expands a list of
      <firstterm>arguments</firstterm> to <firstterm>generate</firstterm>
      completion matches. </para>

    <para>Let us take a <link linkend="usegetopt2">modified version</link>
      of the <emphasis>UseGetOpt.sh</emphasis> script as an example
      command. This script accepts a number of command-line parameters,
      preceded by either a single or double dash. And here is the
      corresponding <firstterm>completion script</firstterm>, by
      convention given a filename corresponding to its associated
      command.</para>

    <example id="usegetoptex">
      <title>Completion script for
      <firstterm>UseGetOpt.sh</firstterm></title>
      <programlisting>&usegetoptex;</programlisting>
    </example>

    <para>Now, let's try it.</para>

  <screen>
<prompt>bash$ </prompt><userinput>source UseGetOpt-2</userinput>

<prompt>bash$ </prompt><userinput>./UseGetOpt-2.sh -[Tab]</userinput>
<computeroutput>--         --aoption  --debug    --file     --help     --log     --test
 -a         -d         -f         -h         -l         -t</computeroutput>


<prompt>bash$ </prompt><userinput>./UseGetOpt-2.sh --[Tab]</userinput>
<computeroutput>--         --aoption  --debug    --file     --help     --log     --test</computeroutput>
  </screen>


    <para>
      We begin by <link linkend="sourceref">sourcing</link> the <quote>completion
      script.</quote> This sets the command-line parameters.
        <footnote><para>Normally the default parameter completion files reside
        in either the <filename class="directory">/etc/profile.d</filename>
	directory or in <filename
	class="directory">/etc/bash_completion</filename>. These autoload on
	system startup. So, after writing a useful completion script, you
	might wish to move it (as <firstterm>root</firstterm>, of course)
	to one of these directories.</para></footnote>
    </para>

    <para>In the first instance, hitting <keycap>[Tab]</keycap> after
      a single dash, the output is all the possible parameters preceded by
      <emphasis>one or more</emphasis> dashes. Hitting <keycap>[Tab]</keycap>
      after <emphasis>two</emphasis> dashes gives the possible parameters
      preceded by <emphasis>two or more</emphasis> dashes.</para>


    <para>Now, just what is the point of having to jump through flaming
      hoops to enable command-line tab completion? <emphasis>It saves
      keystrokes.</emphasis>
         <footnote><para>It has been extensively documented that
         programmers are willing to put in long hours of effort in
         order to save ten minutes of <quote>unnecessary</quote>
         labor. This is known as
         <firstterm>optimization</firstterm>.</para></footnote>
      </para>


    <para>--</para>

    <para><emphasis>Resources:</emphasis></para>

    <para>Bash <ulink url="http://freshmeat.net/projects/bashcompletion">
      programmable completion</ulink> project</para>

    <para>Mitch Frazier's <ulink
    url="http://www.linuxjournal.com"><citetitle
    pubwork="journal">Linux Journal</citetitle></ulink> article, <ulink
    url="http://www.linuxjournal.com/content/more-using-bash-complete-command"><emphasis>More
    on Using the Bash Complete Command</emphasis></ulink></para>

    <para>Steve's excellent two-part article, <quote>An Introduction to Bash
      Completion</quote>:

    <ulink
    url="http://www.debian-administration.org/article/An_introduction_to_bash_completion_part_1">Part
    1</ulink> and

    <ulink url="http://www.debian-administration.org/article/An_introduction_to_bash_completion_part_2">Part 2</ulink></para>

