mirror of
https://github.com/django/django.git
synced 2025-10-24 14:16:09 +00:00
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:
@@ -261,6 +261,82 @@ class ManagementUtility(object):
|
||||
sys.exit(1)
|
||||
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):
|
||||
"""
|
||||
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]",
|
||||
version=get_version(),
|
||||
option_list=BaseCommand.option_list)
|
||||
self.autocomplete()
|
||||
try:
|
||||
options, args = parser.parse_args(self.argv)
|
||||
handle_default_options(options)
|
||||
|
||||
Reference in New Issue
Block a user