From 78bf33f062cfa561ac50cfd01742636211a9c747 Mon Sep 17 00:00:00 2001 From: Jannis Leidel Date: Sat, 7 Nov 2009 04:46:30 +0100 Subject: [PATCH] Added command line completion for bash and zsh --- MANIFEST.in | 1 + docs/index.txt | 11 +++++++ docs/news.txt | 2 ++ pip.py | 45 ++++++++++++++++++++++++++ scripts/completion/pip-completion.bash | 15 +++++++++ scripts/completion/pip-completion.zsh | 17 ++++++++++ 6 files changed, 91 insertions(+) create mode 100644 scripts/completion/pip-completion.bash create mode 100644 scripts/completion/pip-completion.zsh diff --git a/MANIFEST.in b/MANIFEST.in index 5be54085c..1e9fb72b0 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,3 +2,4 @@ recursive-include docs *.txt recursive-include docs *.html recursive-exclude docs/_build *.txt prune docs/_build/_sources +recursive-include scripts/completion * diff --git a/docs/index.txt b/docs/index.txt index f55aad48b..adad77106 100644 --- a/docs/index.txt +++ b/docs/index.txt @@ -251,3 +251,14 @@ If you are using `zc.buildout `_ you should look at `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 + diff --git a/docs/news.txt b/docs/news.txt index f25f06752..6ca8f6ecf 100644 --- a/docs/news.txt +++ b/docs/news.txt @@ -15,6 +15,8 @@ tip * 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. diff --git a/pip.py b/pip.py index a51645c6f..4d11495e2 100755 --- a/pip.py +++ b/pip.py @@ -1182,10 +1182,55 @@ class UnzipCommand(ZipCommand): 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'] diff --git a/scripts/completion/pip-completion.bash b/scripts/completion/pip-completion.bash new file mode 100644 index 000000000..023525c81 --- /dev/null +++ b/scripts/completion/pip-completion.bash @@ -0,0 +1,15 @@ +#!/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 diff --git a/scripts/completion/pip-completion.zsh b/scripts/completion/pip-completion.zsh new file mode 100644 index 000000000..318256116 --- /dev/null +++ b/scripts/completion/pip-completion.zsh @@ -0,0 +1,17 @@ +#!/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 \ No newline at end of file