Ticket #10752: django_bash_completion.4.diff

File django_bash_completion.4.diff, 9.6 KB (added by arthurk, 5 years ago)

Added app completion for some commands

  • django/core/management/__init__.py

    diff -r ceaba5457c05 django/core/management/__init__.py
    a b  
    261261            sys.exit(1)
    262262        return klass
    263263
     264    def autocomplete(self):
     265        """
     266        Output completion suggestions for BASH.
     267
     268        The output of this function is passed to BASH's `COMREPLY` variable and
     269        treated as completion suggestions. `COMREPLY` expects a space
     270        separated string as the result.
     271
     272        The `COMP_WORDS` and `COMP_CWORD` BASH environment variables are used
     273        to get information about the cli input. Please refer to the BASH
     274        man-page for more information about this variables.
     275
     276        Subcommand options are saved as pairs. A pair consists of
     277        the long option string (e.g. '--exclude') and a boolean
     278        value indicating if the option requires arguments. When printing to
     279        stdout, a equal sign is appended to options which require arguments.
     280
     281        Note: If debugging this function, it is recommended to write the debug
     282        output in a separate file. Otherwise the debug output will be treated
     283        and formatted as potential completion suggestions.
     284        """
     285        # don't complete if user hasn't sourced bash_completion file
     286        if not os.environ.has_key('DJANGO_AUTO_COMPLETE'):
     287            return
     288
     289        cwords = os.environ['COMP_WORDS'].split()[1:]
     290        cword = int(os.environ['COMP_CWORD'])
     291
     292        try:
     293            curr = cwords[cword-1]
     294        except IndexError:
     295            curr = ''
     296
     297        subcommands = get_commands().keys() + ['help']
     298        options = [('--help', None)]
     299
     300        # subcommand
     301        if cword == 1:
     302            print ' '.join(filter(lambda x: x.startswith(curr), subcommands))
     303        # subcommand options
     304        # special case: the 'help' subcommand has no options
     305        elif cwords[0] in subcommands and cwords[0] != 'help':
     306            subcommand_cls = self.fetch_command(cwords[0])
     307            # special case: 'runfcgi' stores additional options as
     308            # 'key=value' pairs
     309            if cwords[0] == 'runfcgi':
     310                from django.core.servers.fastcgi import FASTCGI_OPTIONS
     311                options += [(k, 1) for k in FASTCGI_OPTIONS]
     312            # special case: add the names of installed apps to options
     313            elif cwords[0] in ('dumpdata', 'reset', 'sql', 'sqlall',
     314                               'sqlclear', 'sqlcustom', 'sqlindexes',
     315                               'sqlreset', 'sqlsequencereset', 'test'):
     316                from django.conf import settings
     317                # strip "django.contrib" from the app name
     318                options += [(a.replace('django.contrib.', ''), 0)
     319                            for a in settings.INSTALLED_APPS]
     320            options += [(s_opt.get_opt_string(), s_opt.nargs) for s_opt in
     321                        subcommand_cls.option_list]
     322            # filter out previously specified options from available options
     323            prev_opts = [x.split('=')[0] for x in cwords[1:cword-1]]
     324            options = filter(lambda (x, v): x not in prev_opts, options)
     325
     326            # filter options by current input
     327            options = [(k, v) for k, v in options if k.startswith(curr)]
     328            for option in options:
     329                opt_label = option[0]
     330                # append '=' to options which require args
     331                if option[1]:
     332                    opt_label += '='
     333                print opt_label
     334        sys.exit(1)
     335
    264336    def execute(self):
    265337        """
    266338        Given the command-line arguments, this figures out which subcommand is
     
    272344        parser = LaxOptionParser(usage="%prog subcommand [options] [args]",
    273345                                 version=get_version(),
    274346                                 option_list=BaseCommand.option_list)
     347        self.autocomplete()
    275348        try:
    276349            options, args = parser.parse_args(self.argv)
    277350            handle_default_options(options)
  • extras/django_bash_completion

    diff -r ceaba5457c05 extras/django_bash_completion
    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=( $( COMP_WORDS="${COMP_WORDS[*]}" \
     37                   COMP_CWORD=$COMP_CWORD \
     38                       DJANGO_AUTO_COMPLETE=1 $1 ) )
    15039}
    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
     40complete -F _django_completion -o default django-admin.py manage.py
Back to Top