Skip to content

Commit

Permalink
circus-tent#265 - Add autocomplete and bash_completion
Browse files Browse the repository at this point in the history
  • Loading branch information
Natim committed Sep 13, 2012
1 parent 2b79545 commit d71f9e3
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 1 deletion.
45 changes: 44 additions & 1 deletion circus/circusctl.py
Expand Up @@ -5,6 +5,7 @@
import sys
import traceback
import textwrap
import os

# import pygments if here
try:
Expand All @@ -16,7 +17,7 @@

from circus.client import CircusClient
from circus.consumer import CircusConsumer
from circus.commands import get_commands
from circus.commands.base import get_commands, KNOWN_COMMANDS
from circus.exc import CallError, ArgumentError
from circus.util import DEFAULT_ENDPOINT_SUB, DEFAULT_ENDPOINT_DEALER

Expand Down Expand Up @@ -99,6 +100,47 @@ def __init__(self):
'help': 'display version and exit'}
}

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 'AUTO_COMPLETE' not in os.environ:
return

cwords = os.environ['COMP_WORDS'].split()[1:]
cword = int(os.environ['COMP_CWORD'])

try:
curr = cwords[cword-1]
except IndexError:
curr = ''

subcommands = [cmd.name for cmd in KNOWN_COMMANDS]

# subcommand
if cword == 1:
print(' '.join(sorted(filter(lambda x: x.startswith(curr), subcommands))))
sys.exit(1)


def run(self, args):
try:
sys.exit(self.dispatch(args))
Expand All @@ -125,6 +167,7 @@ def get_globalopts(self, args):
return globalopts

def dispatch(self, args):
self.autocomplete()
usage = '%(prog)s [options] command [args]'
parser = argparse.ArgumentParser(
description="Controls a Circus daemon",
Expand Down
37 changes: 37 additions & 0 deletions extras/circusctl_bash_completion
@@ -0,0 +1,37 @@
# #########################################################################
# This bash script adds tab-completion feature to circusctl
#
# Testing it out without installing
# =================================
#
# To test out the completion without "installing" this, just run this file
# directly, like so:
#
# source ~/path/to/circusctl_bash_completion
#
# 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
# ==========
#
# To install this, point to this file from your .bash_profile, like so:
#
# source ~/path/to/circusctl_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
# ============
#
# To uninstall, just remove the line from your .bash_profile and .bashrc.

_circusctl_completion()
{
COMPREPLY=( $( COMP_WORDS="${COMP_WORDS[*]}" \
COMP_CWORD=$COMP_CWORD \
AUTO_COMPLETE=1 $1 ) )
}
complete -F _circusctl_completion -o default circusctl

0 comments on commit d71f9e3

Please sign in to comment.