Fixed #10752. Added more advanced bash completion. Thanks, Arthur Koziel.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@11526 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
a53601c674
commit
677ddcbb04
1
AUTHORS
1
AUTHORS
|
@ -241,6 +241,7 @@ answer newbie questions, and generally made Django that much better:
|
||||||
Igor Kolar <ike@email.si>
|
Igor Kolar <ike@email.si>
|
||||||
Gasper Koren
|
Gasper Koren
|
||||||
Martin Kosír <martin@martinkosir.net>
|
Martin Kosír <martin@martinkosir.net>
|
||||||
|
Arthur Koziel <http://arthurkoziel.com>
|
||||||
Meir Kriheli <http://mksoft.co.il/>
|
Meir Kriheli <http://mksoft.co.il/>
|
||||||
Bruce Kroeze <http://coderseye.com/>
|
Bruce Kroeze <http://coderseye.com/>
|
||||||
krzysiek.pawlik@silvermedia.pl
|
krzysiek.pawlik@silvermedia.pl
|
||||||
|
|
|
@ -261,6 +261,82 @@ class ManagementUtility(object):
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
return klass
|
return klass
|
||||||
|
|
||||||
|
def autocomplete(self):
|
||||||
|
"""
|
||||||
|
Output completion suggestions for BASH.
|
||||||
|
|
||||||
|
The output of this function is passed to BASH's `COMREPLY` variable and
|
||||||
|
treated as completion suggestions. `COMREPLY` expects a space
|
||||||
|
separated string as the result.
|
||||||
|
|
||||||
|
The `COMP_WORDS` and `COMP_CWORD` BASH environment variables are used
|
||||||
|
to get information about the cli input. Please refer to the BASH
|
||||||
|
man-page for more information about this variables.
|
||||||
|
|
||||||
|
Subcommand options are saved as pairs. A pair consists of
|
||||||
|
the long option string (e.g. '--exclude') and a boolean
|
||||||
|
value indicating if the option requires arguments. When printing to
|
||||||
|
stdout, a equal sign is appended to options which require arguments.
|
||||||
|
|
||||||
|
Note: If debugging this function, it is recommended to write the debug
|
||||||
|
output in a separate file. Otherwise the debug output will be treated
|
||||||
|
and formatted as potential completion suggestions.
|
||||||
|
"""
|
||||||
|
# Don't complete if user hasn't sourced bash_completion file.
|
||||||
|
if not os.environ.has_key('DJANGO_AUTO_COMPLETE'):
|
||||||
|
return
|
||||||
|
|
||||||
|
cwords = os.environ['COMP_WORDS'].split()[1:]
|
||||||
|
cword = int(os.environ['COMP_CWORD'])
|
||||||
|
|
||||||
|
try:
|
||||||
|
curr = cwords[cword-1]
|
||||||
|
except IndexError:
|
||||||
|
curr = ''
|
||||||
|
|
||||||
|
subcommands = get_commands().keys() + ['help']
|
||||||
|
options = [('--help', None)]
|
||||||
|
|
||||||
|
# subcommand
|
||||||
|
if cword == 1:
|
||||||
|
print ' '.join(filter(lambda x: x.startswith(curr), subcommands))
|
||||||
|
# subcommand options
|
||||||
|
# special case: the 'help' subcommand has no options
|
||||||
|
elif cwords[0] in subcommands and cwords[0] != 'help':
|
||||||
|
subcommand_cls = self.fetch_command(cwords[0])
|
||||||
|
# special case: 'runfcgi' stores additional options as
|
||||||
|
# 'key=value' pairs
|
||||||
|
if cwords[0] == 'runfcgi':
|
||||||
|
from django.core.servers.fastcgi import FASTCGI_OPTIONS
|
||||||
|
options += [(k, 1) for k in FASTCGI_OPTIONS]
|
||||||
|
# special case: add the names of installed apps to options
|
||||||
|
elif cwords[0] in ('dumpdata', 'reset', 'sql', 'sqlall',
|
||||||
|
'sqlclear', 'sqlcustom', 'sqlindexes',
|
||||||
|
'sqlreset', 'sqlsequencereset', 'test'):
|
||||||
|
try:
|
||||||
|
from django.conf import settings
|
||||||
|
# Get the last part of the dotted path as the app name.
|
||||||
|
options += [(a.split('.')[-1], 0) for a in settings.INSTALLED_APPS]
|
||||||
|
except ImportError:
|
||||||
|
# Fail silently if DJANGO_SETTINGS_MODULE isn't set. The
|
||||||
|
# user will find out once they execute the command.
|
||||||
|
pass
|
||||||
|
options += [(s_opt.get_opt_string(), s_opt.nargs) for s_opt in
|
||||||
|
subcommand_cls.option_list]
|
||||||
|
# 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(curr)]
|
||||||
|
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 execute(self):
|
def execute(self):
|
||||||
"""
|
"""
|
||||||
Given the command-line arguments, this figures out which subcommand is
|
Given the command-line arguments, this figures out which subcommand is
|
||||||
|
@ -272,6 +348,7 @@ class ManagementUtility(object):
|
||||||
parser = LaxOptionParser(usage="%prog subcommand [options] [args]",
|
parser = LaxOptionParser(usage="%prog subcommand [options] [args]",
|
||||||
version=get_version(),
|
version=get_version(),
|
||||||
option_list=BaseCommand.option_list)
|
option_list=BaseCommand.option_list)
|
||||||
|
self.autocomplete()
|
||||||
try:
|
try:
|
||||||
options, args = parser.parse_args(self.argv)
|
options, args = parser.parse_args(self.argv)
|
||||||
handle_default_options(options)
|
handle_default_options(options)
|
||||||
|
|
|
@ -31,136 +31,10 @@
|
||||||
#
|
#
|
||||||
# To uninstall, just remove the line from your .bash_profile and .bashrc.
|
# To uninstall, just remove the line from your .bash_profile and .bashrc.
|
||||||
|
|
||||||
# Enable extended pattern matching operators.
|
|
||||||
shopt -s extglob
|
|
||||||
|
|
||||||
_django_completion()
|
_django_completion()
|
||||||
{
|
{
|
||||||
local cur prev opts actions action_shell_opts action_runfcgi_opts
|
COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \
|
||||||
COMPREPLY=()
|
COMP_CWORD=$COMP_CWORD \
|
||||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
DJANGO_AUTO_COMPLETE=1 $1 ) )
|
||||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
|
||||||
|
|
||||||
# Standalone options
|
|
||||||
opts="--help --settings --pythonpath --noinput --noreload --format --indent --verbosity --adminmedia --version --locale --domain"
|
|
||||||
# Actions
|
|
||||||
actions="createcachetable createsuperuser compilemessages \
|
|
||||||
dbshell diffsettings dumpdata flush inspectdb loaddata \
|
|
||||||
makemessages reset runfcgi runserver shell sql sqlall sqlclear \
|
|
||||||
sqlcustom sqlflush sqlindexes sqlreset sqlsequencereset startapp \
|
|
||||||
startproject syncdb test validate"
|
|
||||||
# Action's options
|
|
||||||
action_shell_opts="--plain"
|
|
||||||
action_runfcgi_opts="host port socket method maxspare minspare maxchildren daemonize pidfile workdir"
|
|
||||||
|
|
||||||
if [[ # django-admin.py, django-admin, ./manage, manage.py
|
|
||||||
( ${COMP_CWORD} -eq 1 &&
|
|
||||||
( ${COMP_WORDS[0]} == django-admin.py ||
|
|
||||||
${COMP_WORDS[0]} == django-admin ||
|
|
||||||
${COMP_WORDS[0]} == ./manage.py ||
|
|
||||||
${COMP_WORDS[0]} == manage.py ) )
|
|
||||||
||
|
|
||||||
# python manage.py, /some/path/python manage.py (if manage.py exists)
|
|
||||||
( ${COMP_CWORD} -eq 2 &&
|
|
||||||
( $( basename -- ${COMP_WORDS[0]} ) == python?([1-9]\.[0-9]) ) &&
|
|
||||||
( $( basename -- ${COMP_WORDS[1]} ) == manage.py) &&
|
|
||||||
( -r ${COMP_WORDS[1]} ) )
|
|
||||||
||
|
|
||||||
( ${COMP_CWORD} -eq 2 &&
|
|
||||||
( $( basename -- ${COMP_WORDS[0]} ) == python?([1-9]\.[0-9]) ) &&
|
|
||||||
( $( basename -- ${COMP_WORDS[1]} ) == django-admin.py) &&
|
|
||||||
( -r ${COMP_WORDS[1]} ) )
|
|
||||||
||
|
|
||||||
( ${COMP_CWORD} -eq 2 &&
|
|
||||||
( $( basename -- ${COMP_WORDS[0]} ) == python?([1-9]\.[0-9]) ) &&
|
|
||||||
( $( basename -- ${COMP_WORDS[1]} ) == django-admin) &&
|
|
||||||
( -r ${COMP_WORDS[1]} ) ) ]] ; then
|
|
||||||
|
|
||||||
case ${cur} in
|
|
||||||
-*)
|
|
||||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
|
||||||
action=$COMPREPLY
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
COMPREPLY=( $(compgen -W "${actions}" -- ${cur}) )
|
|
||||||
action=$COMPREPLY
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
else
|
|
||||||
case ${prev} in
|
|
||||||
dumpdata|reset| \
|
|
||||||
sql|sqlall|sqlclear|sqlcustom|sqlindexes| \
|
|
||||||
sqlreset|sqlsequencereset|test)
|
|
||||||
# App completion
|
|
||||||
settings=""
|
|
||||||
# If settings.py in the PWD, use that
|
|
||||||
if [ -e settings.py ] ; then
|
|
||||||
settings="$PWD/settings.py"
|
|
||||||
else
|
|
||||||
# Use the ENV variable if it is set
|
|
||||||
if [ $DJANGO_SETTINGS_MODULE ] ; then
|
|
||||||
settings=$DJANGO_SETTINGS_MODULE
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
# Couldn't find settings so return nothing
|
|
||||||
if [ -z $settings ] ; then
|
|
||||||
COMPREPLY=()
|
|
||||||
# Otherwise inspect settings.py file
|
|
||||||
else
|
|
||||||
apps=`sed -n "/INSTALLED_APPS = (/,/)/p" $settings | \
|
|
||||||
grep -v "django.contrib" |
|
|
||||||
sed -n "s/^[ ]*'\(.*\.\)*\(.*\)'.*$/\2 /pg" | \
|
|
||||||
tr -d "\n"`
|
|
||||||
COMPREPLY=( $(compgen -W "${apps}" -- ${cur}) )
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
|
|
||||||
createcachetable|cleanup|compilemessages|dbshell| \
|
|
||||||
diffsettings|inspectdb|makemessages| \
|
|
||||||
runserver|startapp|startproject|syncdb| \
|
|
||||||
validate)
|
|
||||||
COMPREPLY=()
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
shell)
|
|
||||||
COMPREPLY=( $(compgen -W "$action_shell_opts" -- ${cur}) )
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
runfcgi)
|
|
||||||
COMPREPLY=( $(compgen -W "$action_runfcgi_opts" -- ${cur}) )
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
host*|port*|socket*|method*|maxspare*|minspare*|maxchildren*|daemonize*|pidfile*|workdir*)
|
|
||||||
if [ "$action" == "runfcgi" ] ; then
|
|
||||||
COMPREPLY=( $(compgen -W "$action_runfcgi_opts" -- ${cur}) )
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
#COMPREPLY=( $(compgen -W "auth core" -- ${cur}) )
|
|
||||||
COMPREPLY=()
|
|
||||||
return 0
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
complete -F _django_completion -o default django-admin.py manage.py
|
||||||
complete -F _django_completion django-admin.py manage.py django-admin
|
|
||||||
|
|
||||||
# Support for multiple interpreters.
|
|
||||||
unset pythons
|
|
||||||
if command -v whereis &>/dev/null; then
|
|
||||||
python_interpreters=$(whereis python | cut -d " " -f 2-)
|
|
||||||
for python in $python_interpreters; do
|
|
||||||
pythons="${pythons} $(basename -- $python)"
|
|
||||||
done
|
|
||||||
pythons=$(echo $pythons | tr " " "\n" | sort -u | tr "\n" " ")
|
|
||||||
else
|
|
||||||
pythons=python
|
|
||||||
fi
|
|
||||||
|
|
||||||
complete -F _django_completion -o default $pythons
|
|
||||||
|
|
Loading…
Reference in New Issue