Ticket #10752: django_bash_completion.diff

File django_bash_completion.diff, 9.5 KB (added by arthurk, 6 years ago)
  • django/core/management/__init__.py

    diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py
    index f1192fe..9bb3303 100644
    a b class ManagementUtility(object): 
    261261                (subcommand, self.prog_name))
    262262            sys.exit(1)
    263263        return klass
    264 
     264   
     265    def autocomplete(self, parser):
     266        """
     267        Outputs a list of bash completion suggestions
     268        """
     269        if os.environ.has_key('DJANGO_AUTO_COMPLETE'):
     270            # map bash variables
     271            cwords = os.environ['COMP_WORDS'].split()
     272            cline = os.environ['COMP_LINE']
     273            cpoint = int(os.environ['COMP_POINT'])
     274            cword = int(os.environ['COMP_CWORD'])
     275
     276            # get all available subcommands & add special cases
     277            completions = get_commands().keys()
     278            completions += ['help',]
     279
     280            # subcommand options completion
     281            if cword >= 2 and cwords[1] in completions:
     282                # 'help' is a special case since it's not a option in
     283                # optparse and handled manually
     284                if cwords[1] == 'help':
     285                    sys.exit(1)
     286
     287                subcommand = self.fetch_command(cwords[1])
     288                subcmd_options = ['--help',]
     289                option_list = []
     290
     291                # runfcgi uses a python dict for its options. add the commands
     292                # manually.
     293                if cwords[1] == 'runfcgi':
     294                    from django.core.servers.fastcgi import FASTCGI_OPTIONS
     295                    subcmd_options = map(lambda x: x+'=', FASTCGI_OPTIONS)
     296                else:
     297                    option_list = subcommand.option_list
     298
     299                # get all options for the subcommand
     300                for opt in option_list:
     301                    opt_label = str(opt)
     302                    # some options are specified in the short/long format
     303                    # e.g. '-e/--exclude'. In this case only the long format
     304                    # is included
     305                    if '/' in opt_label:
     306                        opt_label = opt_label.split('/')[1]
     307
     308                    # append equal sign for options which require arguments
     309                    if opt.nargs:
     310                        opt_label += '='
     311                    subcmd_options.append(opt_label)
     312
     313                # get previously specified options
     314                prev_options = cwords[2:cword]
     315
     316                # remove already specified options
     317                for prev_option in prev_options:
     318                    # check only the key, not the value
     319                    if '=' in prev_option:
     320                        prev_option = prev_option.split('=')[0]+'='
     321
     322                    if prev_option in subcmd_options:
     323                        subcmd_options.remove(prev_option)
     324
     325                # set the remaining options as completion suggestions
     326                completions = subcmd_options
     327            try:
     328                prefix = cwords[cword]
     329            except IndexError:
     330                prefix = None
     331           
     332            # filter completions based on prefix
     333            if prefix:
     334                completions = filter(lambda x: x.startswith(prefix),
     335                                     completions)
     336            # output completions
     337            print ' '.join(completions)
     338            sys.exit(1)
     339   
    265340    def execute(self):
    266341        """
    267342        Given the command-line arguments, this figures out which subcommand is
    class ManagementUtility(object): 
    273348        parser = LaxOptionParser(usage="%prog subcommand [options] [args]",
    274349                                 version=get_version(),
    275350                                 option_list=BaseCommand.option_list)
     351        self.autocomplete(parser)
    276352        try:
    277353            options, args = parser.parse_args(self.argv)
    278354            handle_default_options(options)
  • extras/django_bash_completion

    diff --git a/extras/django_bash_completion b/extras/django_bash_completion
    index b805af9..940b470 100755
    a b  
    3131#
    3232# To uninstall, just remove the line from your .bash_profile and .bashrc.
    3333
    34 # Enable extended pattern matching operators.
    35 shopt -s extglob
    36 
    3734_django_completion()
    3835{
    39     local cur prev opts actions action_shell_opts action_runfcgi_opts
    40     COMPREPLY=()
    41     cur="${COMP_WORDS[COMP_CWORD]}"
    42     prev="${COMP_WORDS[COMP_CWORD-1]}"
    43 
    44     # Standalone options
    45     opts="--help --settings --pythonpath --noinput --noreload --format --indent --verbosity --adminmedia --version --locale --domain"
    46     # Actions
    47     actions="createcachetable createsuperuser compilemessages \
    48              dbshell diffsettings dumpdata flush inspectdb loaddata \
    49              makemessages reset runfcgi runserver shell sql sqlall sqlclear \
    50              sqlcustom sqlflush sqlindexes sqlreset sqlsequencereset startapp \
    51              startproject syncdb test validate"
    52     # Action's options
    53     action_shell_opts="--plain"
    54     action_runfcgi_opts="host port socket method maxspare minspare maxchildren daemonize pidfile workdir"
    55 
    56     if [[ # django-admin.py, django-admin, ./manage, manage.py
    57           ( ${COMP_CWORD} -eq 1 &&
    58             ( ${COMP_WORDS[0]} == django-admin.py ||
    59               ${COMP_WORDS[0]} == django-admin ||
    60               ${COMP_WORDS[0]} == ./manage.py ||
    61               ${COMP_WORDS[0]} == manage.py ) )
    62           ||
    63           # python manage.py, /some/path/python manage.py (if manage.py exists)
    64           ( ${COMP_CWORD} -eq 2 &&
    65             ( $( basename -- ${COMP_WORDS[0]} ) == python?([1-9]\.[0-9]) ) &&
    66             ( $( basename -- ${COMP_WORDS[1]} ) == manage.py) &&
    67             ( -r ${COMP_WORDS[1]} ) )
    68           ||
    69           ( ${COMP_CWORD} -eq 2 &&
    70             ( $( basename -- ${COMP_WORDS[0]} ) == python?([1-9]\.[0-9]) ) &&
    71             ( $( basename -- ${COMP_WORDS[1]} ) == django-admin.py) &&
    72             ( -r ${COMP_WORDS[1]} ) )
    73           ||
    74           ( ${COMP_CWORD} -eq 2 &&
    75             ( $( basename -- ${COMP_WORDS[0]} ) == python?([1-9]\.[0-9]) ) &&
    76             ( $( basename -- ${COMP_WORDS[1]} ) == django-admin) &&
    77             ( -r ${COMP_WORDS[1]} ) ) ]] ; then
    78 
    79         case ${cur} in
    80             -*)
    81                 COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
    82                 action=$COMPREPLY
    83                 return 0
    84                 ;;
    85             *)
    86                 COMPREPLY=( $(compgen -W "${actions}" -- ${cur}) )
    87                 action=$COMPREPLY
    88                 return 0
    89                 ;;
    90         esac
    91     else
    92         case ${prev} in
    93             dumpdata|reset| \
    94             sql|sqlall|sqlclear|sqlcustom|sqlindexes| \
    95             sqlreset|sqlsequencereset|test)
    96                 # App completion
    97                 settings=""
    98                 # If settings.py in the PWD, use that
    99                 if [ -e settings.py ] ; then
    100                     settings="$PWD/settings.py"
    101                 else
    102                     # Use the ENV variable if it is set
    103                     if [ $DJANGO_SETTINGS_MODULE ] ; then
    104                         settings=$DJANGO_SETTINGS_MODULE
    105                     fi
    106                 fi
    107                 # Couldn't find settings so return nothing
    108                 if [ -z $settings ] ; then
    109                     COMPREPLY=()
    110                 # Otherwise inspect settings.py file
    111                 else
    112                     apps=`sed -n "/INSTALLED_APPS = (/,/)/p" $settings | \
    113                           grep -v "django.contrib" |
    114                           sed -n "s/^[ ]*'\(.*\.\)*\(.*\)'.*$/\2 /pg" | \
    115                           tr -d "\n"`
    116                     COMPREPLY=( $(compgen -W "${apps}" -- ${cur}) )
    117                 fi
    118                 return 0
    119                 ;;
    120 
    121             createcachetable|cleanup|compilemessages|dbshell| \
    122             diffsettings|inspectdb|makemessages| \
    123             runserver|startapp|startproject|syncdb| \
    124             validate)
    125                 COMPREPLY=()
    126                 return 0
    127                 ;;
    128             shell)
    129                 COMPREPLY=( $(compgen -W "$action_shell_opts" -- ${cur}) )
    130                 return 0
    131                 ;;
    132             runfcgi)
    133                 COMPREPLY=( $(compgen -W "$action_runfcgi_opts" -- ${cur}) )
    134                 return 0
    135                 ;;
    136             host*|port*|socket*|method*|maxspare*|minspare*|maxchildren*|daemonize*|pidfile*|workdir*)
    137                 if [ "$action"  == "runfcgi" ] ; then
    138                     COMPREPLY=( $(compgen -W "$action_runfcgi_opts" -- ${cur}) )
    139                     return 0
    140                 fi
    141                 return 0
    142                 ;;
    143             *)
    144                 #COMPREPLY=( $(compgen -W "auth core" -- ${cur}) )
    145                 COMPREPLY=()
    146                 return 0
    147                 ;;
    148         esac
    149     fi
     36    COMPREPLY=( $( \
     37        COMP_LINE=$COMP_LINE  COMP_POINT=$COMP_POINT \
     38        COMP_WORDS="${COMP_WORDS[*]}"  COMP_CWORD=$COMP_CWORD \
     39        DJANGO_AUTO_COMPLETE=1 $1 ) )
    15040}
    151 
    152 complete -F _django_completion django-admin.py manage.py django-admin
    153 
    154 # Support for multiple interpreters.
    155 unset pythons
    156 if command -v whereis &>/dev/null; then
    157     python_interpreters=$(whereis python | cut -d " " -f 2-)
    158     for python in $python_interpreters; do
    159         pythons="${pythons} $(basename -- $python)"
    160     done
    161     pythons=$(echo $pythons | tr " " "\n" | sort -u | tr "\n" " ")
    162 else
    163     pythons=python   
    164 fi
    165 
    166 complete -F _django_completion -o default $pythons
     41complete -F _django_completion django-admin.py manage.py
Back to Top