Last active
December 30, 2015 11:19
-
-
Save mitchellrj/7821899 to your computer and use it in GitHub Desktop.
Bash & Zsh autocompletion for Django with extra options (based on Django 1.6)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ######################################################################### | |
# This bash script adds tab-completion feature to django-admin.py and | |
# manage.py. | |
# | |
# Testing it out without installing | |
# ================================= | |
# | |
# To test out the completion without "installing" this, just run this file | |
# directly, like so: | |
# | |
# . ~/path/to/django_bash_completion | |
# | |
# Note: There's a dot ('.') at the beginning of that command. | |
# | |
# After you do that, tab completion will immediately be made available in your | |
# current Bash shell. But it won't be available next time you log in. | |
# | |
# Installing | |
# ========== | |
# | |
# Debian | |
# ------ | |
# Add this file to your /etc/bash_completion.d/ directory | |
# | |
# Non-Debian | |
# ---------- | |
# | |
# To install this, point to this file from your .bash_profile, like so: | |
# | |
# . ~/path/to/django_bash_completion | |
# | |
# Do the same in your .bashrc if .bashrc doesn't invoke .bash_profile. | |
# | |
# Settings will take effect the next time you log in. | |
# | |
# Uninstalling | |
# ============ | |
# | |
# Debian | |
# ------ | |
# Remove this file from your /etc/bash_completion.d/ directory | |
# | |
# Non-Debian | |
# ---------- | |
# | |
# To uninstall, just remove the line from your .bash_profile and .bashrc. | |
_django_completion() | |
{ | |
COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \ | |
COMP_CWORD=$COMP_CWORD \ | |
DJANGO_AUTO_COMPLETE=1 $1 ) ) | |
} | |
complete -F _django_completion -o default django-admin.py manage.py django-admin django | |
_python_django_completion() | |
{ | |
if [[ ${COMP_CWORD} -ge 2 ]]; then | |
PYTHON_EXE=${COMP_WORDS[0]##*/} | |
echo $PYTHON_EXE | egrep "python([2-9]\.[0-9])?" >/dev/null 2>&1 | |
if [[ $? == 0 ]]; then | |
PYTHON_SCRIPT=${COMP_WORDS[1]##*/} | |
echo $PYTHON_SCRIPT | egrep "manage\.py|django-admin(\.py)?" >/dev/null 2>&1 | |
if [[ $? == 0 ]]; then | |
COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]:1}" \ | |
COMP_CWORD=$(( COMP_CWORD-1 )) \ | |
DJANGO_AUTO_COMPLETE=1 ${COMP_WORDS[*]} ) ) | |
fi | |
fi | |
fi | |
} | |
# 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} ${python##*/}" | |
done | |
pythons=$(echo $pythons | tr " " "\n" | sort -u | tr "\n" " ") | |
else | |
pythons=python | |
fi | |
complete -F _python_django_completion -o default $pythons |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#compdef manage.py django-admin.py django-admin django | |
# ------------------------------------------------------------------------------ | |
# Description | |
# ----------- | |
# | |
# Completion script for Django's manage.py (https://www.djangoproject.com). | |
# | |
# Source: https://github.com/technolize/zsh-completion-funcs | |
# | |
# ------------------------------------------------------------------------------ | |
# Authors | |
# ------- | |
# | |
# * technolize (https://github.com/technolize) | |
# | |
# ------------------------------------------------------------------------------ | |
_managepy-cleanup(){} | |
_managepy-compilemessages(){} | |
_managepy-createcachetable(){ | |
_arguments -s : \ | |
$nul_args && ret=0 | |
} | |
_managepy-dbshell(){ | |
_arguments -s : \ | |
$nul_args && ret=0 | |
} | |
_managepy-diffsettings(){ | |
_arguments -s : \ | |
$nul_args && ret=0 | |
} | |
_managepy-dumpdata(){ | |
_arguments -s : \ | |
'--format=-[specifies the output serialization format for fixtures.]:format:(json yaml xml)' \ | |
'--indent=-[specifies the indent level to use when pretty-printing output.]:' \ | |
$nul_args \ | |
'*::appname:_applist' && ret=0 | |
} | |
_managepy-flush(){ | |
_arguments -s : \ | |
'--verbosity=-[verbosity level; 0=minimal output, 1=normal output, 2=all output.]:Verbosity:((0\:minimal 1\:normal 2\:all))' \ | |
'--noinput[tells Django to NOT prompt the user for input of any kind.]' \ | |
$nul_args && ret=0 | |
} | |
_managepy-help(){ | |
_arguments -s : \ | |
'*:command:_managepy_cmds' \ | |
$nul_args && ret=0 | |
} | |
_managepy_cmds(){ | |
local line | |
local -a cmd | |
_call_program help-command ./manage.py help \ | |
|& sed -n '/^ /s/[(), ]/ /gp' \ | |
| while read -A line; do cmd=($line $cmd) done | |
_describe -t managepy-command 'manage.py command' cmd | |
} | |
_managepy-inspectdb(){ | |
_arguments -s : \ | |
$nul_args && ret=0 | |
} | |
_managepy-loaddata(){ | |
_arguments -s : \ | |
'--verbosity=-[verbosity level; 0=minimal output, 1=normal output, 2=all output.]:Verbosity:((0\:minimal 1\:normal 2\:all))' \ | |
'*::file:_files' \ | |
$nul_args && ret=0 | |
} | |
_managepy-makemessages(){} | |
_managepy-reset(){ | |
_arguments -s : \ | |
'--noinput[tells Django to NOT prompt the user for input of any kind.]' \ | |
'*::appname:_applist' \ | |
$nul_args && ret=0 | |
} | |
_managepy-runfcgi(){ | |
local state | |
local fcgi_opts | |
fcgi_opts=( | |
'protocol[fcgi, scgi, ajp, ... (default fcgi)]:protocol:(fcgi scgi ajp)' | |
'host[hostname to listen on..]:' | |
'port[port to listen on.]:' | |
'socket[UNIX socket to listen on.]::file:_files' | |
'method[prefork or threaded (default prefork)]:method:(prefork threaded)' | |
'maxrequests[number of requests a child handles before it is killed and a new child is forked (0 = no limit).]:' | |
'maxspare[max number of spare processes / threads.]:' | |
'minspare[min number of spare processes / threads.]:' | |
'maxchildren[hard limit number of processes / threads.]:' | |
'daemonize[whether to detach from terminal.]:boolean:(False True)' | |
'pidfile[write the spawned process-id to this file.]:file:_files' | |
'workdir[change to this directory when daemonizing.]:directory:_files' | |
'outlog[write stdout to this file.]:file:_files' | |
'errlog[write stderr to this file.]:file:_files' | |
) | |
_arguments -s : \ | |
$nul_args \ | |
'*: :_values "FCGI Setting" $fcgi_opts' && ret=0 | |
} | |
_managepy-runserver(){ | |
_arguments -s : \ | |
'--noreload[tells Django to NOT use the auto-reloader.]' \ | |
'--adminmedia[specifies the directory from which to serve admin media.]:directory:_files' \ | |
$nul_args && ret=0 | |
} | |
_managepy-shell(){ | |
_arguments -s : \ | |
'--plain[tells Django to use plain Python, not IPython.]' \ | |
$nul_args && ret=0 | |
} | |
_managepy-sql(){} | |
_managepy-sqlall(){} | |
_managepy-sqlclear(){} | |
_managepy-sqlcustom(){} | |
_managepy-sqlflush(){} | |
_managepy-sqlindexes(){} | |
_managepy-sqlinitialdata(){} | |
_managepy-sqlreset(){} | |
_managepy-sqlsequencereset(){} | |
_managepy-startapp(){} | |
_managepy-startproject(){ | |
_arguments -s : \ | |
"(-v --verbosity)"{-v,--verbosity}"[Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output.]:Verbosity:((0\:minimal 1\:normal 2\:verbose 4\:very\ verbose))" \ | |
'--template[The path or URL to load the template from.]:file:_files' \ | |
"(-e --extension)"{-e,--extension}"[The file extension(s) to render (default: "py"). Separate multiple extensions with commas, or use -e multiple times.]" \ | |
"(-n --name)"{-n,--name}"[The file name(s) to render. Separate multiple extensions with commas, or use -n multiple times. --version show program\'s version number and exit]:file:_files" \ | |
$nul_args \ | |
'*::args:_gnu_generic' | |
} | |
_managepy-syncdb() { | |
_arguments -s : \ | |
'--verbosity=-[verbosity level; 0=minimal output, 1=normal output, 2=all output.]:Verbosity:((0\:minimal 1\:normal 2\:all))' \ | |
'--noinput[tells Django to NOT prompt the user for input of any kind.]' \ | |
$nul_args && ret=0 | |
} | |
_managepy-test() { | |
_arguments -s : \ | |
'--verbosity=-[verbosity level; 0=minimal output, 1=normal output, 2=all output.]:Verbosity:((0\:minimal 1\:normal 2\:all))' \ | |
'--noinput[tells Django to NOT prompt the user for input of any kind.]' \ | |
'*::appname:_applist' \ | |
$nul_args && ret=0 | |
} | |
_managepy-testserver() { | |
_arguments -s : \ | |
'--verbosity=-[verbosity level; 0=minimal output, 1=normal output, 2=all output.]:Verbosity:((0\:minimal 1\:normal 2\:all))' \ | |
'--addrport=-[port number or ipaddr:port to run the server on.]' \ | |
'*::fixture:_files' \ | |
$nul_args && ret=0 | |
} | |
_managepy-validate() { | |
_arguments -s : \ | |
$nul_args && ret=0 | |
} | |
_managepy-changepassword(){} | |
_managepy-createsuperuser(){} | |
_managepy-collectstatic(){} | |
_managepy-findstatic(){} | |
_managepy-commands() { | |
local -a commands | |
commands=( | |
'cleanup:Can be run as a cronjob or directly to clean out old data from the database (only expired sessions at the moment).' | |
'compilemessages:Compiles .po files to .mo files for use with builtin gettext support.' | |
'createcachetable:creates the table needed to use the SQL cache backend.' | |
'dbshell:runs the command-line client for the current DATABASE_ENGINE.' | |
"diffsettings:displays differences between the current settings.py and Django's default settings." | |
'dumpdata:Output the contents of the database as a fixture of the given format.' | |
'flush:Executes ``sqlflush`` on the current database.' | |
'help:manage.py help.' | |
'inspectdb:Introspects the database tables in the given database and outputs a Django model module.' | |
'loaddata:Installs the named fixture(s) in the database.' | |
'makemessages:Runs over the entire source tree of the current directory and pulls out all strings marked for translation.' | |
'reset:Executes ``sqlreset`` for the given app(s) in the current database.' | |
'runfcgi:Run this project as a fastcgi (or some other protocol supported by flup) application,' | |
'runserver:Starts a lightweight Web server for development.' | |
'shell:Runs a Python interactive interpreter.' | |
'sql:Prints the CREATE TABLE SQL statements for the given app name(s).' | |
'sqlall:Prints the CREATE TABLE, custom SQL and CREATE INDEX SQL statements for the given model module name(s).' | |
'sqlclear:Prints the DROP TABLE SQL statements for the given app name(s).' | |
'sqlcustom:Prints the custom table modifying SQL statements for the given app name(s).' | |
'sqlflush:Returns a list of the SQL statements required to return all tables in the database to the state they were in just after they were installed.' | |
'sqlindexes:Prints the CREATE INDEX SQL statements for the given model module name(s).' | |
"sqlinitialdata:RENAMED: see 'sqlcustom'" | |
'sqlreset:Prints the DROP TABLE SQL, then the CREATE TABLE SQL, for the given app name(s).' | |
'sqlsequencereset:Prints the SQL statements for resetting sequences for the given app name(s).' | |
"startapp:Creates a Django app directory structure for the given app name in this project's directory." | |
"startproject:Creates a Django project directory structure for the given project name in the current directory or the given destination." | |
"syncdb:Create the database tables for all apps in INSTALLED_APPS whose tables haven't already been created." | |
'test:Runs the test suite for the specified applications, or the entire site if no apps are specified.' | |
'testserver:Runs a development server with data from the given fixture(s).' | |
'validate:Validates all installed models.' | |
) | |
if [[ $words[1] =~ "manage.py$" ]]; then | |
commands=($commands | |
"changepassword:Change a user's password for django.contrib.auth." | |
'createsuperuser:Used to create a superuser.' | |
'collectstatic:Collect static files in a single location.' | |
'findstatic:Finds the absolute paths for the given static file(s).' | |
) | |
fi | |
_describe -t commands 'manage.py command' commands && ret=0 | |
} | |
_applist() { | |
local line | |
local -a apps | |
_call_program help-command "python -c \"import os.path as op, re, settings, sys;\\ | |
bn=op.basename(op.abspath(op.curdir));[sys\\ | |
.stdout.write(str(re.sub(r'^%s\.(.*?)$' % | |
bn, r'\1', i)) + '\n') for i in settings.\\ | |
INSTALLED_APPS if re.match(r'^%s' % bn, i)]\"" \ | |
| while read -A line; do apps=($line $apps) done | |
_values 'Application' $apps && ret=0 | |
} | |
_manage.py() { | |
local -a nul_args | |
nul_args=( | |
'--settings=-[the Python path to a settings module.]:file:_files' | |
'--pythonpath=-[a directory to add to the Python path.]::directory:_directories' | |
'--traceback[print traceback on exception.]' | |
"--version[show program's version number and exit.]" | |
{-h,--help}'[show this help message and exit.]' | |
) | |
local curcontext=$curcontext ret=1 | |
if ((CURRENT == 2)); then | |
_managepy-commands | |
else | |
shift words | |
(( CURRENT -- )) | |
curcontext="${curcontext%:*:*}:managepy-$words[1]:" | |
_call_function ret _managepy-$words[1] | |
fi | |
} | |
_manage.py "$@" | |
# Local Variables: | |
# mode: Shell-Script | |
# sh-indentation: 2 | |
# indent-tabs-mode: nil | |
# sh-basic-offset: 2 | |
# End: | |
# vim: ft=zsh sw=2 ts=2 et |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment