Ticket #10752: django_bash_completion.2.diff

File django_bash_completion.2.diff, 9.3 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..8139c9b 100644
    a b class ManagementUtility(object): 
    261261                (subcommand, self.prog_name))
    262262            sys.exit(1)
    263263        return klass
    264 
     264   
     265    def autocomplete(self):
     266        """
     267        Output a list of completion suggestions for BASH.
     268       
     269        The output of this function is passed to BASH's `COMREPLY` variable and
     270        treated as completion suggestions. `COMREPLY` expects a space
     271        separated string as the result.
     272       
     273        The `COMP_WORDS` and `COMP_CWORD` BASH environment variables are used
     274        to get information about the cli input. Please refer to the BASH
     275        man-page for more information about this variables.
     276       
     277        Subcommand options are saved as pairs. A pair consists of
     278        the long option string (e.g. '--exclude', not '-e') and a boolean
     279        value indicating if the option requires arguments.
     280       
     281        When printing to stdout, a equal sign is appended to options which
     282        require arguments.
     283       
     284        Note: If debugging this function, it is recommended to write debug
     285        output in a separate file. Otherwise the debug output will be treated
     286        and formatted as potential completion suggestions.
     287        """
     288        # don't complete if user hasn't sourced bash_completion file
     289        if not os.environ.has_key('DJANGO_AUTO_COMPLETE'):
     290            return
     291       
     292        cwords = os.environ['COMP_WORDS'].split()[1:]
     293        cword = int(os.environ['COMP_CWORD'])
     294       
     295        try:
     296            curr = cwords[cword-1]
     297        except IndexError:
     298            curr = ''
     299       
     300        subcommands = get_commands().keys() + ['help']
     301        options = [('--help', None)]
     302
     303        # subcommand
     304        if cword == 1:
     305            print ' '.join(filter(lambda x: x.startswith(curr), subcommands))
     306        # subcommand options
     307        # special case: the 'help' subcommand has no options
     308        elif cwords[0] in subcommands and cwords[0] != 'help':
     309            subcommand_cls = self.fetch_command(cwords[0])
     310            # special case: 'runfcgi' stores additional options as
     311            # 'key=value' pairs
     312            if cwords[0] == 'runfcgi':
     313                from django.core.servers.fastcgi import FASTCGI_OPTIONS
     314                options += [(k, 1) for k in FASTCGI_OPTIONS]
     315            options += [(s_opt.get_opt_string(), s_opt.nargs) for s_opt in
     316                        subcommand_cls.option_list]
     317            # filter out previously specified options from available options
     318            prev_opts = [x.split('=')[0] for x in cwords[1:cword-1]]
     319            options = filter(lambda (x, v): x not in prev_opts, options)
     320           
     321            # filter options by current input
     322            options = [(k, v) for k, v in options if k.startswith(curr)]
     323            for option in options:
     324                opt_label = option[0]
     325                # append '=' to options which require args
     326                if option[1]:
     327                    opt_label += '='
     328                print opt_label
     329        sys.exit(1)
     330   
    265331    def execute(self):
    266332        """
    267333        Given the command-line arguments, this figures out which subcommand is
    class ManagementUtility(object): 
    273339        parser = LaxOptionParser(usage="%prog subcommand [options] [args]",
    274340                                 version=get_version(),
    275341                                 option_list=BaseCommand.option_list)
     342        self.autocomplete()
    276343        try:
    277344            options, args = parser.parse_args(self.argv)
    278345            handle_default_options(options)
  • extras/django_bash_completion

    diff --git a/extras/django_bash_completion b/extras/django_bash_completion
    index b805af9..5dc3515 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=( $( 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 django-admin.py manage.py
Back to Top