Commits

Jannis Leidel  committed eecd62a

Added command line completion for bash and zsh

  • Participants
  • Parent commits 012e00f
  • Branches trunk

Comments (0)

Files changed (6)

 recursive-include docs *.html
 recursive-exclude docs/_build *.txt
 prune docs/_build/_sources
+recursive-include scripts/completion *

File docs/index.txt

 <http://pypi.python.org/pypi/zc.buildout>`_ you should look at
 `gp.recipe.pip <http://pypi.python.org/pypi/gp.recipe.pip>`_ as an
 option to use pip and virtualenv in your buildouts.
+
+Command line completion
+-----------------------
+
+pip comes with completion scripts for bash and zsh, which live in
+``scripts/completion`` of the pip source distribution. They allow you
+to use tab completion of the commands and options. Simply source the
+appropriate file, e.g.::
+
+    source /path/to/pip/scripts/completion/pip-completion.bash
+

File docs/news.txt

 * Allow installing/upgrading to Package==dev (fix "Source version does not
   match target version" errors).
 
+* Added command and option completion for bash and zsh.
+
 * Extended integration with virtualenv by providing an option to
   automatically use an active virtualenv and an option to warn if no active
   virtualenv is found.
 
 UnzipCommand()
 
+def autocomplete():
+    """Command and option completion for the main option parser (and options)
+    and its subcommands (and options).
+
+    Enable by sourcing one of the completion shell scripts (bash or zsh).
+    """
+    # Don't complete if user hasn't sourced bash_completion file.
+    if not os.environ.has_key('PIP_AUTO_COMPLETE'):
+        return
+    cwords = os.environ['COMP_WORDS'].split()[1:]
+    cword = int(os.environ['COMP_CWORD'])
+    try:
+        current = cwords[cword-1]
+    except IndexError:
+        current = ''
+    subcommands = _commands.keys()
+    options = []
+    # subcommand
+    if cword == 1:
+        # show options of main parser only when necessary
+        if current.startswith('-') or current.startswith('--'):
+            subcommands += [opt.get_opt_string()
+                            for opt in parser.option_list
+                            if opt.help != optparse.SUPPRESS_HELP]
+        print ' '.join(filter(lambda x: x.startswith(current), subcommands))
+    # subcommand options
+    # special case: the 'help' subcommand has no options
+    elif cwords[0] in subcommands and cwords[0] != 'help':
+        subcommand = _commands.get(cwords[0])
+        options += [(opt.get_opt_string(), opt.nargs)
+                    for opt in subcommand.parser.option_list
+                    if opt.help != optparse.SUPPRESS_HELP]
+        # filter out previously specified options from available options
+        prev_opts = [x.split('=')[0] for x in cwords[1:cword-1]]
+        options = filter(lambda (x, v): x not in prev_opts, options)
+        # filter options by current input
+        options = [(k, v) for k, v in options if k.startswith(current)]
+        for option in options:
+            opt_label = option[0]
+            # append '=' to options which require args
+            if option[1]:
+                opt_label += '='
+            print opt_label
+    sys.exit(1)
 
 def main(initial_args=None):
     if initial_args is None:
         initial_args = sys.argv[1:]
+    autocomplete()
     options, args = parser.parse_args(initial_args)
     if options.help and not args:
         args = ['help']

File scripts/completion/pip-completion.bash

+#!/bin/sh
+# pip command and option completion for bash shell.
+# You need to source this shell script with a command like this::
+#
+#   source /path/to/pip-completion.bash
+#
+
+_pip_completion()
+{
+    COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \
+                   COMP_CWORD=$COMP_CWORD \
+                   PIP_AUTO_COMPLETE=1 $1 ) )
+}
+
+complete -o default -F _pip_completion pip

File scripts/completion/pip-completion.zsh

+#!/bin/sh
+# pip command and option completion for zsh shell.
+# You need to source this shell script with a command like this::
+#
+#   source /path/to/pip-completion.zsh
+#
+
+function _pip_completion {
+  local words cword
+  read -Ac words
+  read -cn cword
+  reply=( $( COMP_WORDS="$words[*]" \
+             COMP_CWORD=$(( cword-1 )) \
+             PIP_AUTO_COMPLETE=1 $words[1] ) )
+}
+
+compctl -K _pip_completion pip